Запись OO Javascript с помощью jQuery
Я исхожу из фона прототипа 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 и этот шаблон.
Спасибо заранее.
Ответы
Ответ 1
Вы можете абсолютно привязать событие к чему-то другому, кроме элемента 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(), она все равно отменит правильную функцию, если передала оригинал.
Ответ 2
Я откатываю свои собственные объекты на основе этой хорошей статьи:
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, как и выше, и, как и некоторые другие ответы ниже. В конце концов, просто напишите синтаксис, с которым вам комфортно. Предложение использовать кофе Script тоже круто - все, что плавает на вашей лодке:)
Ответ 3
Вам не нужно 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!
}
};
Теперь для более сложных классов с наследованием я использую John Resig простое наследование класса.
Я также разделяю классы на файлы, завернутые с закрытием. Это будет PageHelper.js
:
;!!window['APP'] && (function (NS, $) {
NS.PageHelper = Class.extend({ // see link above
// functions
init: function () { // constructor
},
displayMessage: function() {
}
});
})(window['APP'], jQuery);
Ответ 4
Если вы ищете несколько схожую структуру ООП для JQuery, вы можете попробовать http://code.google.com/p/jquery-klass/
Это то, что я использую.
Ответ 5
Я нахожу запись кода OO в CoffeeScript намного приятнее, чем Class.create()
или более низкий уровень prototype
. Ознакомьтесь с разделом привязки функций.
Ответ 6
Я думаю, что лучшая реализация класса jQuery принадлежит блогу Джона Ресига (http://ejohn.org/blog/simple-javascript-inheritance/). Я очень рекомендую это; он очень похож на Prototype JS.
Я написал библиотеку поверх нее, чтобы упростить дизайн OO внутри 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
}
});