Published Properties

Jim Tang edited this page Aug 29, 2012 · 5 revisions

Published Properties

enyo.Object

enyo.Object implements the Enyo framework's property publishing system. Published properties are declared in a hash called published within a call to enyo.kind. Getter and setter methods are automatically generated for properties declared in this manner. Also, by convention, the setter for a published property will trigger an optional <propertyName>Changed method when called.

In the following example, myValue becomes a regular property on the "MyObject" prototype (with a default value of 3), and the getter and setter methods are generated as noted in the comments:

enyo.kind({
	name: "MyObject",
	kind: enyo.Object,

	// declare 'published' properties
	published: {
		myValue: 3
	},

	// These methods will be automatically generated:
	//	getMyValue: function() ...
	//	setMyValue: function(inValue) ...

	// optional method that is called whenever setMyValue is called
	myValueChanged: function(inOldValue) {
		this.delta = this.myValue - inOldValue;
	}
});

Since we have declared a property changed method (i.e., myValueChanged) to observe set calls on the myValue property, it will be called when setMyValue is called, as illustrated by the following:

myobj = new MyObject();
var x = myobj.getMyValue(); // x gets 3

myobj.setMyValue(7); // myValue becomes 7; myValueChanged side-effect sets delta to 4

Property changed methods are only called when setters are invoked with a different value. If you were to call setMyValue a second time with the same value, the changed handler would not be invoked:

myobj.setMyValue(7); // myValue stays 7; myValueChanged is *not* called

Published properties are stored as regular properties on the object prototype, so it's possible to query or set their values directly:

var x = myobj.myValue;

Note that when you set a property's value directly, the property changed method is not called.

Object and Array Values

In most cases, published properties should only contain basic values, such as numbers and strings. If you use an array or an object as the value of a property, the mechanism that detects changes will likely fail. This is because JavaScript comparisons only change the outermost object. A getProperty call that returns an object or array returns a reference to the internal state, since if you then modify that object or array, you modify the same instance that's held inside the kind instance.

You could work around this by overriding getProperty to have it use enyo.clone to make a shallow copy of the object or array. Then, if you pass that object into setProperty, it won't be considered equal to the internal one, since it's a different object in memory. However, you would have a new problem in that propertyChanged will be called even if the two objects have all the same contents.