我一直在jQuery中实现一种发布者/订阅者设计模式.我基本上是在Javascript中使用CoffeeScript构建类,它们作为我页面上的组件.即导航,数据列表等
我没有让DOM元素触发事件,而是让这些类的实例使用触发器来发送自定义事件.然后,这些实例可以相互监听,并可以根据彼此行为的变化相应地更新它们拥有的DOM元素!
我知道这是有效的,因为我有一个组件正确调度自定义事件.但是,我遇到了麻烦.我创造了另一个组件,对于我的生活,我无法弄清楚为什么它的事件没有被解雇.
这是我班级的实施:
window.List = (function() {
List = function(element, settings) {
var _a, _b, _c;
this.list = $(element);
this.settings = jQuery.extend(List.DEFAULTS, settings);
this.links = this.list.find(this.settings.link_selector);
this.links.selectable();
_b = [SelectableEvent.COMPLETED, SelectableEvent.UNDONE, SelectableEvent.SELECTED, SelectableEvent.DESELECTED];
for (_a = 0, _c = _b.length; _a < _c; _a++) {
(function() {
var event_type = _b[_a];
return this.links.bind(event_type, __bind(function(event, selectable_event) {
return this.dispatch(selectable_event);
}, this));
}).call(this);
}
return this;
};
List.DEFAULTS = {
link_selector: "a",
completed_selector: ".completed"
};
List.prototype.change = function(mode, previous_mode) {
if (mode !== this.mode) {
this.mode = mode;
if (previous_mode) {
this.list.removeClass(previous_mode);
}
return this.list.addClass(this.mode);
}
};
List.prototype.length = function() {
return this.links.length;
};
List.prototype.remaining = function() {
return this.length() - this.list.find(this.settings.completed_selector).length;
};
List.prototype.dispatch = function(selectable_event) {
$(this).trigger(selectable_event.type, selectable_event);
return alert(selectable_event.type);
};
return List;
}).call(this);
注意:
List.prototype.dispatch = function(selectable_event) {
$(this).trigger(selectable_event.type, selectable_event);
return alert(selectable_event.type);
};
正确触发此代码并通过警报返回预期的事件类型.但在警报之前,预计会触发自定义事件.这是我遇到问题的地方.
$(document).ready(function() {
var list_change_handler, todo_list;
todo_list = new List("ul.tasks");
list_change_handler = function(event, selectable_event) {
return alert("Hurray!");
};
$(todo_list).bind(SelectableEvent.COMPLETED, list_change_handler);
$(todo_list).bind(SelectableEvent.UNDONE, list_change_handler);
$(todo_list).bind(SelectableEvent.SELECTED, list_change_handler);
$(todo_list).bind(SelectableEvent.DESELECTED, list_change_handler);
}
你在这里看到警报“Hurray”是我想解雇的,但不幸的是我在这里没有运气.具有讽刺意味的是,我已经完成了同样的事情与另一个类实现相同的方式调度自定义事件和监听器接收它就好了.为什么这不起作用的任何想法?
更新:
在评论中讨论,看起来在控制台中记录“this”会返回表示类的JS对象.但是记录“$(this)”会返回一个空的jQuery对象,因此永远不会触发触发器.当“this”准确地返回类的实例时,有关为什么$(this)出现空的任何想法?
解决方法:
我发现jQuery无法索引我的对象,因为该类实现了它自己的jQuery方法版本.在这种情况下,length().将length()方法重命名为total()可以完全解决问题,并且该类的任何实例都可以成功触发事件.