javascript property change event

被刻印的时光 ゝ 提交于 2019-11-29 07:54:43

问题


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.


回答1:


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

You could 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.

$(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');



回答2:


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:

https://github.com/benjamine/tent

It's documented with JSDoc and unit tested with 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.




回答3:


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:

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



回答4:


You could try Javascript Property Events (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.

Sample of normal defineProperty:

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

Sample of property with onchange event:

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


来源:https://stackoverflow.com/questions/4169524/javascript-property-change-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!