非DOM对象的JavaScript事件处理(注册多个处理程序)
问题描述:
在.NET中,您可以将多个处理程序添加到对象声明为事件的事件中。非DOM对象的JavaScript事件处理(注册多个处理程序)
在JavaScript中处理非DOM对象的推荐方式是什么?
即我有一个对象:
var ProblemDomainObj = {} ;
ProblemDomainObj.Changed = function() {} ;
ProblemDomainObj.Data = { somedata : "initialized" } ;
ProblemDomainObj.Operate = function (newdata) {
if (newdata != somedata && ProblemDomainObj.IsValid(newdata)) {
somedata = newdata;
ProblemDomainObj.Changed();
}
} ;
现在其他对象可能要注册到知道数据已发生变化,每个想要做这样的事情:
ProblemDomainObj.Changed += function() {
/* Do stuff to reflect the object model changes */
} ;
如果每个获得注册他们的处理程序而不覆盖另一个。
然后一些对象会调用ProblemDomainObj.Operate(foo);
,所有已订阅的人都会收到通知。
我在jQuery中找到了http://api.jquery.com/on/的文档,但它似乎与像onclick这样的DOM事件有关。这些都不一定与DOM有关。
答
jQuery对常规对象也很棒:http://jsfiddle.net/gMNkg/。
var ProblemDomainObj = {};
ProblemDomainObj.Data = { somedata : "initialized" };
ProblemDomainObj.Operate = function() {
$(ProblemDomainObj).trigger("foo"); // run bound functions
};
// bind 2 functions
$(ProblemDomainObj).on("foo", function() {
alert(123);
});
$(ProblemDomainObj).on("foo", function() {
alert(456);
});
ProblemDomainObj.Operate();
答
下面是使用封闭
ProblemDomainObj.Changed = (function(previousChangeEvent) {
return function() {
if (previousChangeEvent) {
previousChangeEvent();
}
/* Do stuff to reflect the object model changes */
}
})(ProblemDomainObj.Changed) ;
答
function PubSub() {
return {
events: {},
sub: function (event, handler) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(handler);
},
pub: function (event, data) {
this.events[event] && this.events[event].forEach(publishData);
function publishData(handler) {
handler(data);
};
}
};
}
var pubsub = PubSub();
pubsub.sub("changed", f);
pubsub.sub("changed", g);
pubsub.pub("changed", o);
你基本上要一个微小的事件系统,你可以说:“我想订阅此事件”和“我要发布此事件”的一种方式。
我建议你写自己的小事件系统。
您必须将此对象集成到您的系统中。它可能最适合作为混合使用。
答
假设您使用jQuery,您可以在任何对象上添加自定义事件。
var obj = {a:1,b:2};
$(obj).on('changed', function() { alert('Changed once'); });
$(obj).on('changed', function() { alert('Changed twice'); });
$(obj).trigger('changed');
你写C#中的JavaScript。您可能想要退后一步并完全学习JavaScript – Raynos
@Raynos JavaScript中是否存在原生习惯,否定了订阅对象事件的需要,以便您可以将组件解耦以了解其他组件,以了解想要了解有关它们引发的事件的其他组件? –
不,但写一个是10行,如图所示 – Raynos