sylvainpolletvillard / ObjectModel

Strong Dynamically Typed Object Modeling for JavaScript
http://objectmodel.js.org
MIT License
467 stars 28 forks source link

Is it possible to observe properties of model objects? #56

Closed Yiin closed 7 years ago

Yiin commented 7 years ago

So when property is changed, I can know that, w/o creating getters and setters.

Using Vue2 and ES6

sylvainpolletvillard commented 7 years ago

Hi,

I guess you can use an assertion to do something like that, although they are not supposed to be used this way. If you change some data in the watcher callback, ObjectModel won't be able to check the data or may cause an infinite loop. Also, an assertion may be called more than once for a single change, depending on the model complexity.

const User = new ObjectModel({
  name: Model(String).assert(function onNameChanged(){ 
      console.log("name has changed", arguments); 
      return true; // always validate the assert
  })
});

This goes beyond the scope of ObjectModel, so I would not recommend to rely on this for important stuff.

The "best way" in my opinion would be to add a Proxy by yourself around the model instance. For example:

const User = new ObjectModel({
    name: String
});

User.create = function(props){
   return new Proxy(new User(props), {
      set: function(obj, prop, value){
         console.log(prop + " has changed to value " + value + " for obj", obj)
    return Reflect.set(obj, prop, value) // apply default behaviour
      }
   })
}

const joe = User.create({ name: "joe" })

joe.name = "Jack"
// name has changed to value Jack for obj Proxy {name: "joe"}
Yiin commented 7 years ago

Alright, thank you so much for detailed response. :) Wrapping custom proxy around model instance definitely looks like the way to go.

sylvainpolletvillard commented 7 years ago

Happy to help. Proxies are awesome :)