Skip to content

Instantly share code, notes, and snippets.

@jaz303
Last active August 29, 2015 13:57
Show Gist options
  • Save jaz303/9688740 to your computer and use it in GitHub Desktop.
Save jaz303/9688740 to your computer and use it in GitHub Desktop.
// signal is a function that creates an object to which listeners
// can be attached. think of it like an EventEmitter with a single
// event.
var signal = require('signalkit');
function property(value) {
var sig = signal();
var prop = function(newValue) {
if (arguments.length === 0) {
return value;
} else {
var oldValue = value;
value = newValue;
sig.emit(prop, value, oldValue);
return true;
}
}
prop.onChange = sig;
return prop;
}
function property(value) {
var sig = signal();
var prop = {
get: function() {
return value;
},
set: function(newValue) {
oldValue = value;
value = newValue;
sig.emit(prop, value, oldValue);
return true;
},
onChange: sig
}
}
@latentflip
Copy link

var myage = property(10);
myage.onChange.connect(function (v) { alert(v); })
myage();
myage(20);
var myage = property(10);
myage.onChange.connect(function (v) { alert(v); })
myage.set(20);
myage.get();

@latentflip
Copy link

As standalone object, I think the first way is two confusing. It might make more sense as part of another object:

var phil = {
  age: property(10);
}

phil.age() //=> 10
phil.age(20)

but if you were going to do that, why not just use Object.defineProperty.

@jaz303
Copy link
Author

jaz303 commented Mar 21, 2014

I agree it looks better that way.

I'm not using Object.defineProperty because I'm building a UI that edits a dozen or so properties at once, and those properties do not all belong to the same object. There's also a bunch of other metadata like title and the type of widget used to edit each property. Also, the list of editable properties is not static and I need to be able watch for properties being added/deleted.

Another option is to do away with fine-grained property objects and just have the user provide an object that satisfies a simple API like this:

delegate.getEditablePropertyNames() // => ['foo', 'bar', 'baz']
delegate.get('foo') // => 10
delegate.set('foo', 20) // => true
delegate.get('foo') // => 20

Or I guess I could extend that to generating an on-demand proxy-object with Object.defineProperty + getters/setters, but I'd still need an auxiliary API for monitoring changes.

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