我需要在每次更新/更改属性时触发事件,以使dom元素与模型上的属性值保持同步(我使用john resig的简单继承http://ejohn.org/blog/simple-javascript-inheritance/)。这可以通过跨浏览器方式进行吗?在我看来,如果我可以包装js用于设置属性的任何函数并使其触发事件,它可以工作,我只是不知道该怎么做。
答案 0 :(得分:9)
JavaScript不使用函数来设置属性。它们只是变量,设置它们不需要任何复杂的包装器。
你 可以使用函数来设置属性 - 您可以在支持类中私有数据的语言中使用相同类型的getter / setter排列。这样,您的函数可以轻松运行已注册为回调的其他函数。使用jQuery,您甚至可以将它们作为事件来处理。
$(yourObject).bind('some-event-you-made-up', function() {
// This code will run whenever some-event-you-made-up is triggered on yourObject
});
// ...
$(yourObject).trigger('some-event-you-made-up');
答案 1 :(得分:2)
也许你已经用jQuery绑定/触发器解决了你的问题,但是我想告诉我我正在建立一个变更跟踪和(在其中)实体建模Javascript框架,名为“tent”,它解决了你暴露的问题,无需任何关于对象操作的特殊语法,其开源并托管在:
https://github.com/benjamine/tent
用JSDoc记录,并用js-test-driver测试单元。
您可以这样使用更改跟踪模块:
var myobject = { name: 'john', age: 34 };
// add a change handler that shows changes on alert dialogs
tent.changes.bind(myobject, function(change) {
alert('myobject property '+change.data.propertyName+' changed!');
});
myobject.name = 'charly'; // gets notified on an alert dialog
它也适用于数组更改(添加,删除)。 此外,您可以使用“实体”上下文来保留所有检测到的更改(添加,删除,修改项目)的更改集,这些更改按集合,级联添加和删除,保持反向属性同步,跟踪1对1,1对N和N对M的关系等。
答案 2 :(得分:0)
Object defineProperty / defineProperties可以解决问题。 这是一个简单的代码。我已经构建了一些基于它的数据绑定框架,它可能变得非常复杂,但是为了这样做:
var oScope = {
$privateScope:{},
notify:function(sPropertyPath){
console.log(sPropertyPath,"changed");
}
};
Object.defineProperties(oScope,{
myPropertyA:{
get:function(){
return oScope.$privateScope.myPropertyA
},
set:function(oValue){
oScope.$privateScope.myPropertyA = oValue;
oScope.notify("myPropertyA");
}
}
});
oScope.myPropertyA = "Some Value";
//console will log: myPropertyA changed
答案 3 :(得分:-1)
您可以尝试Javascript Property Events (jpe.js)
我遇到了类似的问题,最后为Object.defineProperty编写了一个重载函数,它将事件处理程序添加到属性中。它还提供类型检查(js-base-types)并在内部存储其值,以防止不必要的更改。
正常的defineProperty示例:
Object.defineProperty(document, "property", {
get:function(){return myProperty},
set:function(value){myProperty = value},
})
var myProperty = false;
onchange事件的属性示例:
Object.defineProperty(document, "property", {
default:false,
get:function(){},
set:function(value){},
onchange:function(event){console.info(event)}
})