Every uiElement
based object has an observe
method. This method allows you to turn any value into a Knockout.js observable.
UiElement = requirejs('uiElement');
object = new UiElement;
object.foo = 'bar';
object.observe('foo');
console.log(object.foo());
As you can see from the above, we’ve turned the foo
property, formerly a string, into a an observable while maintaining its value. If you look at the source of the observe
method
observe: function (useAccessors, properties) {
var model = this,
trackMethod;
if (typeof useAccessors !== 'boolean') {
properties = useAccessors;
useAccessors = false;
}
trackMethod = useAccessors ? accessor : observable;
if (_.isString(properties)) {
properties = properties.split(' ');
}
if (Array.isArray(properties)) {
properties.forEach(function (key) {
trackMethod(model, key, model[key]);
});
} else if (typeof properties === 'object') {
_.each(properties, function (value, key) {
trackMethod(model, key, value);
});
}
return this;
},
You’ll see Magento has gotten a little (too?) clever with the arguments for this method. If the first parameter to observe
is a boolean, and if that boolean is true
, then Magento will observe the property not via an observable, but via the knockout-es5 plugin’s track
method (discussed in the Observables, uiElement Objects, and Variable Tracking article.
object = new UiElement
object.baz = "Hello"
object.observe(true, 'baz');
object.on('baz', function(value){
console.log("called");
});
object.baz = "Setting A new value"
Magento also has an alias for this “boolean first” syntax – the track
method.
//functionality equivalent
object.track('baz');
object.observe(true, 'baz');
If you’re a close follower of my writing, you’ll remember I previously warned you off track
. That was an error on my part – track
works perfectly fine, I had just forgotten that observables only fire their subscribers when a value changes
Finally, either track
or observe
will accept a list of properties as an array or a space separated string.
object.track('foo bar baz');
object.observe(true, 'foo bar baz');
object.track(['foo', 'bar', 'baz']);
object.observe(true, 'foo', 'bar', 'baz');