[Adding laszlo-dev]

Just to be clear:

The purpose of the setter property on an attribute is to allow you to create a 'virtual' attribute. It allows you to intercept the setting of the attribute and do arbitrary computations. Potentially, you could store the value (state) of the attribute in another attribute (which might or might not be public). The canonical example of a virtual attribute is a dimension in a different unit, e.g., you might have an Angle object with degrees and radians attributes, only one of which is actually stored, the other being a virtual attribute that converts to/from the 'native' unit.

In LZX there is an additional wrinkle, because of events. Normally, without a custom setter, an event is sent every time you set an attribute. Adam felt that there might, just might, be a case where you didn't want to send an event (or would want to send several); so, when you give an attribute a custom setter, you have to handle the event sending in your setter.

Finally, Eliot's example could be made more efficient by not having the separate _setFoo method, just putting the body of _setFoo in the setter field. I realize this makes the code less legible.

We have several times discussed how to improve the legibility of setters. If we were to adopt a more JS2-like approach, you would write:

<attribute name="degrees" allocation="virtual" />
<method name="set degrees" args="newValue">
  this.setAttribute('radians', degreesToRadians(newValue));
  if (this.ondegrees.ready) { this.ondegrees.sendEvent(newValue); }
</method>
<method name="get degrees">
  return radiansToDegrees(this.radians);
</method>

(Both the 'set foo' and 'get foo' methods could still be written in- line in the attribute tag too. In fact, specifying a getter or setter should imply that the attribute is virtual, e.g:

<attribute name="degrees" getter="radiansToDegrees(this.radians)" />
<method name="set degrees" args="newValue">
  this.setAttribute('radians', degreesToRadians(newValue));
  if (this.ondegrees.ready) { this.ondegrees.sendEvent(newValue); }
</method>

should be equivalent.  The long-hand form is just for legibility.)

On 2007-11-01, at 18:05 EDT, Elliot Winard wrote:

This is used in a bunch of places in Webtop.

By having a setter you can have code that runs before the onattribute events fire.
Most instances of the pattern look like this -


<attribute name="foo" setter="this._setFoo(foo)" />
<event name="onfoo" />
<method name="_setFoo" args="foo">
    // do something special that must run before onfoo events fire
    this.foo=foo;
    if (onfoo) onfoo.sendEvent();
</method>


Yup,
-e
On Thu, Nov 1, 2007 at  5:38 PM, Benjamin Shine wrote:

The code from the guy who is rotating OpenLaszlo in webkit[1] includes this:

   <attribute name="wrot" type="number" value="0"
     setter="this.wrot = wrot; this.updateRot(wrot);"/>

I've never seen this "setter" attribute-of-an-attribute before. Is this still a supported and/or recommended API?

-ben


[1] http://www.cuppadev.co.uk/2007/10/31/rotating-openlaszlo-with-webkit/

Reply via email to