Написание OO Javascript с помощью jQuery - PullRequest
13 голосов
/ 06 мая 2011

Я пришел из Prototype JS, где OO Javascript поощряется использованием Class.create().Сейчас я выполняю некоторую работу с JQuery и пытаюсь написать некоторый правильно структурированный код JQuery, где я могу, например, вызвать одну и ту же объектную функцию из двух разных обработчиков событий щелчка.

Вот код в Prototype:

document.observe("dom:loaded", function() {

    // create document
    APP.pageHelper = new APP.PageHelper();


});

// namespace our code
window.APP = {};

// my class
APP.PageHelper = Class.create({

  // automatically called
  initialize: function(name, sound) {
    this.myValue = "Foo";

    // attach event handlers, binding to 'this' object
    $("myButton").observe("click", this.displayMessage.bind(this))

  },

  displayMessage: function() {
    console.log("My value: " + this.myValue); // 'this' is the object not the clicked button!
  }

});

Мне интересно, как следующий код может быть реплицирован в JQuery, где нет способа привязать вызов функции к объекту, который он называетсяв, и 'this' всегда является элементом, по которому щелкнули.

Я слышал о способе сделать это с помощью шаблона «модуля» Дугласа Крокфорда (http://www.yuiblog.com/blog/2007/06/12/module-pattern/), но мне бы очень хотелось, чтобы кто-нибудь показал мне, как вы реализуете приведенный выше код, используя JQuery и этот шаблон.

Заранее спасибо.

Ответы [ 6 ]

4 голосов
/ 06 мая 2011

Я создаю свои собственные объекты на основе этой хорошей статьи:

http://www.klauskomenda.com/code/javascript-programming-patterns/

Я просто выбираю тот шаблон, который имеет смысл для проекта, над которым я работаю. Например, быстрый пример выполнения того, что вы просите:

$.myNamespace.myClass = function (options) {
    this.settings = $.extend({ ... defaults ... }, options);
    this.init();
};
$.myNamespace.myClass.prototype.settings = {
    someValue: 'default',
    someSelector: '#myButton'
};
$.myNamespace.myClass.prototype.init = function () {
    var self = this;
    $(self.settings.someSelector).click(function (event) {
        console.log(self.settings.someValue);
    });
};

Вы ответили ниже, что знаете о прототипе, но синтаксис немного раздражает. Я думаю, что это просто вопрос привыкания к одному синтаксису над другим. Я уверен, что библиотека Prototype использует замыкания и .prototype точно так же, как я делал выше и как некоторые другие ответы предлагают ниже. В конце просто напишите синтаксис, который вам удобнее. Предложение использовать Coffee Script тоже круто - все, что плывет на вашей лодке:)

3 голосов
/ 06 мая 2011

Вы можете абсолютно привязать событие к чему-то другому, кроме элемента dom. Просто используйте $.proxy.

Описание:

Принимает функцию и возвращает новую, которая всегда будет иметь определенный контекст. добавлена ​​версия: 1.4

 /**
  * @param function - The function whose context will be changed.
  * @param context - The object to which the context (this) of the function should be set.
  */
jQuery.proxy( function, context )

Этот метод наиболее полезен для присоединения обработчиков событий к элементу, контекст которого указывает на другой объект. Кроме того, jQuery гарантирует, что даже если вы свяжете функцию, возвращенную из jQuery.proxy (), она все равно отменит правильную функцию, если передаст оригинал.

1 голос
/ 15 июня 2012

Если вы ищете похожую структуру ООП для JQuery, вы можете попробовать http://code.google.com/p/jquery-klass/

Это то, что я использую.

1 голос
/ 06 мая 2011

Вам не нужно Class.create() для написания классов в javascript.

APP.PageHelper = function(name, sound) { // this is the constructor
    this.myValue = "Foo";
    // attach event handlers, binding to 'this' object
    $('#myButton').click($.proxy(this.displayMessage, this)); // use $.proxy instead of `bind`
}
APP.PageHelper.prototype = { // define more prototype functions here
    displayMessage: function() {
        console.log("My value: " + this.myValue); // 'this' is the object not the clicked button!
    }
};

Теперь для более сложных классов с наследованием я использую простое наследование классов Джона Ресига .

Я также разделяю классы на файлы, завернутые в замыкание.Это будет PageHelper.js:

;!!window['APP'] && (function (NS, $) {
    NS.PageHelper = Class.extend({ // see link above
        // functions
        init: function () { // constructor

        },
        displayMessage: function() { 

        }
    });
})(window['APP'], jQuery);
0 голосов
/ 15 июля 2011

Я думаю, что лучшая реализация класса jQuery из блога Джона Ресига (http://ejohn.org/blog/simple-javascript-inheritance/). Я очень рекомендую его; он очень похож на Prototype JS.

Я написал библиотеку для упрощения проектирования ОО в jQuery (https://github.com/arturnt/brickjs). Например, чтобы сделать то, что вы делаете, вы можете сделать следующее.

Comp.APP = {}; Comp.APP.PageHelper = Comp.extend({ init: function(e) { this._super(e); this.myValue = "foo"; }, "#myButton click": function() { console.log(this.myValue); //prints } });

0 голосов
/ 06 мая 2011

Я считаю, что написание OO-кода в CoffeeScript гораздо приятнее, чем Class.create() или более низкий уровень prototype. Ознакомьтесь с разделом о привязке функций .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...