Skip to content

Instantly share code, notes, and snippets.

@muraiki
Created March 19, 2015 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muraiki/5cc72eaeb20a57da31bc to your computer and use it in GitHub Desktop.
Save muraiki/5cc72eaeb20a57da31bc to your computer and use it in GitHub Desktop.
KO model with getters/setters and json update support
function FooModel () {
Object.defineProperties(this, {
_foo: {
value: ko.observable(x.name),
enumerable: true,
configurable: true
},
_bar: {
value: ko.observable(x.server_id || x.instance_id || x.instanceId),
enumerable: true,
configurable: true
},
_dontupdatethisone: {
value: ko.observable(x.project_id),
enumerable: true,
configurable: true
}
});
var self = this;
// Generate public properties and Obs suffixed accessors; make source
// property "private"
var generateProperties = function (key) {
// Create a property that accesses the underlying observable
Object.defineProperty(self, key.substring(1) + "Obs", {
enumerable: true,
value: self[key]
});
// Create the "public" property
Object.defineProperty(self, key.substring(1), {
enumerable: true,
get: function () { return self[key](); },
set: function (n) { self[key](n); }
});
// Hide the "private" property
Object.defineProperty(self, key, {
enumerable: false, configurable: false
});
};
// Generate additional properties for all _-prefixed properties
_(self)
.keys()
.filter(function (key) { return _.startsWith(key, "_"); })
.value()
.forEach(generateProperties);
/*** Handle Updating ***/
// map the keys in json to the properties on your model
var desiredKeys = {
"foo": "foo",
"bar": "bar"
};
Object.defineProperty(self, 'updateFromJson', {
enumerable: true,
value: function (data) {
Object.keys(data)
.forEach(function (key) {
var modelKey = desiredKeys[key];
if (!modelKey) return;
if ( !_.isEqual(self[modelKey], data[key]) )
self[modelKey] = data[key]; // I can use = syntax because I use Object.defineproperty with setters
});
}
});
}
@muraiki
Copy link
Author

muraiki commented Mar 19, 2015

whoops, FooModel should take an argument, x, which is used in the constructor. and you can see various bits of OpenStack data structures referenced there, hehe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment