Opened 9 years ago

Closed 9 years ago

Last modified 6 years ago

#10839 closed defect (fixed)

Provide a generic interface and base class for getting, setting, and watching for property changes (with getters and setters) in a consistent manner

Reported by: Kris Zyp Owned by: Kris Zyp
Priority: high Milestone: 1.5
Component: General Version: 1.4.0
Keywords: Cc:
Blocked By: Blocking:

Description (last modified by Eugene Lazutkin)

This ticket proposes the addition of a dojo.Stateful class, providing the ability to monitor stateful objects in dojo with a watch()}} method. The {{{watch() method would be based on Mozilla's Object.prototype.watch (1):

obj.watch(propertyName, callback); // monitor a property

or

obj.watch(callback); // monitor any property change for that object

The two primary types of objects that I would like to be able to monitor are widgets and data store objects. We have recently discussed using a different data/object store approach whereby data store objects could be provide a consistent set of methods, and watch() could certainly be one of them. dijit._Widget will extend from dojo.Stateful and thus deliver notifications to listeners for any attribute changes. The ability to watch an object would be discerned with feature detection (the presence of obj.watch), but would hopefully be available at least on all widgets (although user objects could implement this ability as well).

One of the primary motivations for this design, is would enable building functionally reactive "live" templating engines or data-bindings on top of Dojo. The concepts of functional reactive design (or data-bindings) have been demonstrated in other projects like Flex, Flapjax (2), and Fin (3). There recently has been interest expressed in developing a template language with these type of data-binding capabilities that could run on Dojo, where one could write something like:

<div>${obj.foo}</div>

or

<div>${obj.get("foo")}</div>

And the variable/object property would be evaluated when the template is executed, and the templating engine would then automatically "watch" the obj's foo property for any changes and automatically rerender the template when the value changes. This is a powerful concept because it can remove a significant amount of user code for event propagation and rerendering.

I think another beneficial pattern for clarity of code with code-based attribute access is the use of get()/set() pattern for code-controlled property access. We have discussed this before, but I think this is much clearer the current widget attr() that handles both gets and sets. watch()/get()/set() would make a clear easy-to-use pattern for interacting with widgets.

(1) https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Object/watch

(2) http://www.flapjax-lang.org/

(3) http://ajaxian.com/archives/fin-self-updating-template-language

Attachments (2)

Stateful.js (4.1 KB) - added by Kris Zyp 9 years ago.
dojo.Stateful
watchable_Widget.diff (2.1 KB) - added by Kris Zyp 9 years ago.
dijit._Widget

Download all attachments as: .zip

Change History (39)

Changed 9 years ago by Kris Zyp

Attachment: Stateful.js added

dojo.Stateful

Changed 9 years ago by Kris Zyp

Attachment: watchable_Widget.diff added

dijit._Widget

comment:1 Changed 9 years ago by Eugene Lazutkin

Description: modified (diff)

Reformatting.

comment:2 Changed 9 years ago by Kris Zyp

(In [21666]) Addition of dojo.Stateful for get/set/watch objects, refs #10839

comment:3 Changed 9 years ago by Kris Zyp

(In [21667]) Addition of dojo.Stateful for get/set/watch objects, refs #10839 !strict

comment:4 Changed 9 years ago by bill

(In [21676]) just fixing doc typo, the first parameter to watch() is optional, not the second, refs #10839.

comment:5 Changed 9 years ago by bill

(In [21677]) just fixing doc typo, the first parameter to watch() is optional, not the second, refs #10839.

comment:6 Changed 9 years ago by Kris Zyp

(In [21687]) Reverts _Widget extending dojo.Stateful, and fixes connection points to attr method, refs #10839 !strict

comment:7 Changed 9 years ago by Kris Zyp

(In [21689]) Changes grid handling of get() to be compatible with _Widget, refs #10839 !strict

comment:8 Changed 9 years ago by Kris Zyp

(In [21754]) Support hash based sets, refs #10839 !strict

comment:9 Changed 9 years ago by Kris Zyp

(In [21755]) Added improved get/set docs, updated tests, and support hash based sets, refs #10839 !strict

comment:10 Changed 9 years ago by bill

(In [21764]) fix syntax errors from [21755], refs #10839

comment:11 Changed 9 years ago by Kris Zyp

(In [21779]) Fix Tree + JRS test, refs #10839

comment:12 Changed 9 years ago by bill

(In [21781]) Rollback strange change from [21755], was this checked in by accident? Buttons do not support width/height setting. Refs #10839.

comment:13 Changed 9 years ago by bill

(In [21782]) API doc for hash based sets, refs #10839

comment:14 Changed 9 years ago by bill

(In [21783]) Update API doc (mainly for deprecated methods), redirecting to use set()/get(), rather than redirecting to use attr(). Also added API doc for set() of hash based sets. Refs #10839 !strict.

comment:15 Changed 9 years ago by bill

(In [21784]) Conversion of Widget internal this.attr() calls to this.get()/this.set() calls, refs #10839 !strict. (There are lots more calls left though.)

comment:16 Changed 9 years ago by bill

(In [21786]) Need to connect to set() not to attr(), in case set() is called directly. Refs #10839 !strict.

comment:17 Changed 9 years ago by bill

(In [21787]) Conversion of remaining dijit attr() calls to get()/set() calls, refs #10839 !strict.

comment:18 Changed 9 years ago by Jared Jurkiewicz

(In [21820]) Missed a conversion of an attr call. refs #10839

comment:19 Changed 9 years ago by Jared Jurkiewicz

(In [21821]) Converting a bunch of dojox Editor plugin calls to yse get/set instead of attr. \!strict refs #10839

comment:20 Changed 9 years ago by Jared Jurkiewicz

(In [21839]) Fixing usage of attr to get/set to remove deprecation warnings. refs #10839

comment:21 Changed 9 years ago by Kris Zyp

(In [21858]) Reverted change to test tree data structure, Fix Tree + JRS test, refs #10839

comment:22 Changed 9 years ago by bill

(In [21864]) Only print attr() deprecation warning once per calling function, refs #10839 !strict.

comment:23 Changed 9 years ago by bill

(In [21957]) attr() --> get()/set(), refs #10839 !strict

comment:24 Changed 9 years ago by bill

(In [22068]) attr() --> get()/set(), refs #10839 !strict

comment:25 Changed 9 years ago by bill

See also [22101]: Figure.get -> Figure.getAnnotator to avoid conflicting with the new set/get style

comment:26 Changed 9 years ago by bill

Milestone: tbd1.5
Owner: changed from anonymous to Kris Zyp

See also #11105.

comment:27 Changed 9 years ago by Kris Zyp

(In [22138]) Fixes |this| for callbacks, refs #10839

comment:28 Changed 9 years ago by bill

(In [22237]) Fix problem in attr() deprecation warning when arguments.callee.caller is null. Fixes #11203, refs #10839 !strict.

comment:29 Changed 9 years ago by bill

I filed #11251 for the _Widget.watch() feature. I think you can close this ticket now?

comment:30 Changed 9 years ago by Kris Zyp

Resolution: fixed
Status: newclosed

comment:31 Changed 9 years ago by bill

(In [22543]) fix comment, refs #10839 !strict

comment:32 Changed 9 years ago by bill

(In [22773]) Refactor TitlePane so set("open", ...) is main interface to open/close, rather than toggle(). This also moves the CSS code (including _setCss() call) from postCreate() into _setOpenAttr() thus doing no CSS changes in postCreate(). Refs #10839, #11635 !strict.

comment:33 Changed 9 years ago by bill

(In [22834]) update comments from attr() --> get()/set(), refs #10839 !strict

comment:34 Changed 8 years ago by Kris Zyp

(In [23669]) Make a copy of callbacks before iterating to avoid iteration conflicts, refs #10839

comment:35 Changed 7 years ago by bill

In [30263]:

fix order of arguments to doh.is() (should be: expected, actual), refs #10839

comment:36 Changed 6 years ago by Bill Keese <bill@…>

In 59323f72ec1b98270fec565da6d30efd96fd7fbe/dijit:

Error: Processor CommitTicketReference failed
Unsupported version control system "git": Can't find an appropriate component, maybe the corresponding plugin was not enabled? 

comment:37 Changed 6 years ago by Bill Keese <bill@…>

In d71e794118448491b18bf92a7643f4cda544162c/dijit:

Error: Processor CommitTicketReference failed
Unsupported version control system "git": Can't find an appropriate component, maybe the corresponding plugin was not enabled? 
Note: See TracTickets for help on using tickets.