public
Last active — forked from /stalkable.js

  • Download Gist
examples.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/**
The idea here is that all changes to your new object can be observed
*/
Ember.View.extend({
model: Ember.StalkableObject.create(),
saveModel: Ember.observer(function () {
/** do some fancy stuff to save changes to your model */
}, 'model.@properties')
});
 
Ember.View.extend({
model: Ember.StalkableObject.create({ host: null, port: null }),
saveModel: Ember.observer(function () {
/** this will only be called when changes to the 'host' and 'port' are changed */
}, 'model.@initProperties')
});
 
Ember.View.extend({
model: App.MyStalkableModel.create(),
saveModel: Ember.observer(function () {
/** this will only be called when changes to the prototyped properties of App.MyStalkableModel are changed */
}, 'model.@prototypeProperties')
});
 
Ember.View.extend({
model: Ember.StalkableObject.create({ nonce: null }),
saveModel: Ember.observer(function () {
/** this will be called on changes any properties that are undefined at instantiation (i.e., excluding all the
stuff on Object, as well as "nonce", which we expect to change frequently.) */
}, 'model.@ownProperties')
});
stalkable.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
/*jslint nomen:true */
/**
"Stalkable" objects can be watched for any and all changes
@author Bryan Elliott <belliott@rsicms.com>
*/
(function (global) {
"use strict";
var Ember = global.Ember;
/**
Detect whether an Object is using this Mixin
*/
Ember.Mixin.prototype.detectInstance = function (object) {
/*jslint forin:true */
var name,
mixins = object[Ember.META_KEY].mixins;
for (name in mixins) {
if (this.detect(mixins[name])) {
return true;
}
}
return false;
};
/**
Changes to Ember.CoreObject that enable property stalking via the pseudoproperties: "@properties", "@ownProperties", and "@prototypeProperties"
*/
Ember.Stalkable = Ember.Mixin.create({
setUnknownProperty: function (key, value) {
var ret = this._super.apply(this, arguments);
this.observeNewProperty(key);
return ret;
},
observeNewProperty: function (key, isProto) {
var inst = this,
isInit = inst.constructor.prototype.hasOwnProperty(key),
clean,
handler = function () {
clean = !inst.modifiedProperties;
if (clean) {
inst.modifiedProperties = [ key ];
} else {
inst.modifiedProperties.push(key);
}
if (!isProto && !isInit) {
inst.notifyPropertyChange("@ownProperties");
} else if (isInit && !isProto) {
inst.notifyPropertyChange("@initProperties");
} else {
inst.notifyPropertyChange("@prototypeProperties");
}
inst.notifyPropertyChange("@properties");
if (clean) {
delete inst.modifiedProperties;
}
};
this.addObserver(key, this, handler);
if (!isProto) { handler(); }
},
setProperties: function () {
var ret;
this.modifiedProperties = [];
ret = this._super.apply(this, arguments);
delete this.modifiedProperties;
return ret;
}
});
 
/**
Small modification to CoreObject.create for Stalkables
*/
Ember.CoreObject.reopenClass({
create: function () {
/*jslint forin:true */
var i, name, args, caught = {},
ret = this._super.apply(this, arguments);
if (Ember.Stalkable.detectInstance(ret)) {
args = [].slice.apply(arguments);
for (i = 0; i < args.length; i += 1) {
for (name in args[i]) {
if (!(args[i][name] instanceof Function)) {
ret.observeNewProperty(name);
caught[name] = true;
}
}
}
for (name in ret) {
if (!caught[name]) {
ret.observeNewProperty(name, true)
}
}
}
return ret;
}
});
Ember.StalkableObject = Ember.Object.extend(Ember.Stalkable);
}(this));

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.