javascript 属性更改事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4169524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:13:21  来源:igfitidea点击:

javascript property change event

javascriptjquerywatch

提问by joshontheweb

I need to fire an event every time a property is updated/changed in order to keep dom elements in sync with the property values on the model (Im using john resig's simple inheritance http://ejohn.org/blog/simple-javascript-inheritance/). Is this possible to do in a cross-browser way? It seems to me that if I could wrap whatever function js uses to set properties and make it fire an event, that it could work, Im just not sure how to do that.

每次更新/更改属性时,我都需要触发一个事件,以使 dom 元素与模型上的属性值保持同步(我使用 john resig 的简单继承http://ejohn.org/blog/simple-javascript-继承/)。这可以以跨浏览器的方式进行吗?在我看来,如果我可以包装 js 用来设置属性的任何函数并让它触发一个事件,它就可以工作,我只是不知道该怎么做。

回答by VoteyDisciple

JavaScript doesn't use a function to set properties. They're just variables, and setting them doesn't require any elaborate wrappers.

JavaScript 不使用函数来设置属性。它们只是变量,设置它们不需要任何复杂的包装器。

Youcould use a function to set the property, though — the same sort of a getter/setter arrangement you might use in a language that supported private data in classes. In that way your function could easily run other functions that have been registered as callbacks. Using jQuery you can even handle those as events.

不过,您可以使用函数来设置属性——这与您可能在支持类中私有数据的语言中使用的 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');

回答by Benja

Maybe you already solved your problem with jQuery bind/trigger, but I wanted to tell that I'm building a Change Tracking and (in top of that) Entity Modeling Javascript Framework, named "tent" that solves the problem you exposed, without requiring any special syntax on object manipulation, its open source and hosted at:

也许你已经用 jQuery 绑定/触发器解决了你的问题,但我想告诉你我正在构建一个变更跟踪和(最重要的)实体建模 Javascript 框架,名为“帐篷”,它解决了你暴露的问题,而不需要关于对象操作的任何特殊语法,其开源并托管在:

https://github.com/benjamine/tent

https://github.com/benjamine/tent

It's documented with JSDoc and unit tested with js-test-driver.

它使用 JSDoc 进行了记录,并使用 js-test-driver 进行了单元测试。

you can use the change tracking module this way:

您可以这样使用更改跟踪模块:

   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

it works with Array changes too (adds, deletes). Further you can use "Entity" Contexts to keep a changesets of all detected changes (ADDED, DELETED, MODIFIED items) grouped on collections, cascade adds and deletes, keep reverse properties synced, track 1-to-1, 1-to-N and N-to-M relationships, etc.

它也适用于数组更改(添加、删除)。此外,您可以使用“实体”上下文来保留所有检测到的更改(添加、删除、修改项目)的变更集,按集合分组,级联添加和删除,保持反向属性同步,跟踪 1 对 1、1 对 N和 N 对 M 的关系等。

回答by Guilherme Ferreira

Object defineProperty/defineProperties does the trick. Here goes a simple code. I have built some data binding frameworks based on that, and it can get really complex, but for exercising its like this:

对象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

回答by E. P. de Haas

You could try Javascript Property Events (jpe.js)

您可以尝试Javascript 属性事件 (jpe.js)

I encountered a similar issue, and ended up writing an overload function for Object.defineProperty that adds event handlers to the properties. It also provides type checking (js-base-types) and stores its value internally, preventing unwanted changes.

我遇到了类似的问题,最终为 Object.defineProperty 编写了一个重载函数,将事件处理程序添加到属性中。它还提供类型检查 (js-base-types) 并在内部存储其值,以防止不必要的更改。

Sample of normal defineProperty:

正常defineProperty的示例:

Object.defineProperty(document, "property", {
    get:function(){return myProperty},
    set:function(value){myProperty = value},
})
var myProperty = false;

Sample of property with onchange event:

带有 onchange 事件的属性示例:

Object.defineProperty(document, "property", {
    default:false,
    get:function(){},
    set:function(value){},
    onchange:function(event){console.info(event)}
})