How can I add observer to ALL properties of an object?

I have user object in my app that I want to keep same across all open tabs. I’ve got everything done but triggering sync on any property change part. Is there a way to observe all property changes, or really having 32-items long .obeserve() is the only way?

If you are changing so many things at once, you might want to look at setting up an action that updates your views. In theory if you are binding the data correctly everything should auto-update by itself.

This however is a workaround: Get all your 32 keys from the object and set the observer programatically on init.

user: Ember.Object.create({
  foo: 'bar',
  bar: 'foo',
  hallo: 'hola'
}),

init: function() {
  this._super.apply(this, arguments);

  var user     = this.get('user');
  var userKeys = Ember.keys(user);
  var self     = this;

  userKeys.forEach(function(key) {
    user.addObserver(key, self, 'onUserChange');
  });
},

onUserChange: function() {
  alert('user changed');
}
3 Likes

I have this same issue.

I would like to avoid a list of multiple observers that also have to be maintained, so I tried someone else’s idea of a mixin that overrides Ember.Object’s set method:

export default Ember.Mixin.create({
	set: function(key, value) {
		this._super(key, value);
		if (key !== 'hasChanged') {
			console.debug("hasChanged");
			this.set('hasChanged', key);
		}
		return this;
	},
});

then

var observable = Ember.Object.createWithMixins(PropertyWatchMixin, {});

But it doesn’t work, at least not with Ember 1.11.3: the overriden setter never gets called. Are getters/setters not overridable? Any other way this could work?

UPDATE: Actually, this does work. My actual problem is form controls are not calling the set method. I’ll leave this here just in case it’s helpful for someone.

Indeed, set method is not usually called. It is a very common practice to alias Ember.set and use it directly. That skips a level of indirection, and has the benefit of working on any object, not just Ember.Observable subclasses.

I guess you could add some metadata to the properties you want to track so you can recognize them later. I believe ember-data’s attr function does something like this.