[dojo-contributors] MVC support for dijit based on dojo.Stateful

Bill Keese bill at dojotoolkit.org
Sun Mar 6 18:08:01 EST 2011


OK, it seems confusing that an app can specify either ref or binding, and
they can essentially be the same thing:

     new dijit.form.TextBox({ref: 'myStatefulModel.employeeName'})

vs.

     new dijit.form.TextBox({binding: myStatefulModel.employeeName})

Typically how this is done in dojo is to separate the object and the
attribute, ex:

    dojo.connect(obj, "attr", ...)

What if you did that instead?   If you separated out the parameters like
dojo.connect() does then a simple binding would look like:

  <input id="zipInput" data-dojo-type="dijit.form.NumberTextBox"
data-dojo-props="binding: loanModel, ref: "zip"">

A binding with a parent would look like:

    <div data-dojo-type="dijit.mvc.Group" data-dojo-props="binding:
searchRecords">

      <input data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: '
Query'/>



The hard part becomes nested relative bindings, but I guess it could be
ref's all the way down, except for the top level node:


     <div data-dojo-type="dijit.mvc.Group" data-dojo-props="binding:
searchRecords">

      <div data-dojo-type="dijit.mvc.Repeat" data-dojo-props="ref: 'Results
'">

          <input data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: '
Query'/>




On Mon, Mar 7, 2011 at 7:00 AM, Rahul Akolkar <rahul.akolkar at gmail.com>wrote:

> Hi Bill,
>
> Inline.
>
> On Sat, Mar 5, 2011 at 9:09 PM, Bill Keese <bill at dojotoolkit.org> wrote:
> > OK, so part of what I was asking was whether parent.get("ref") just
> returned
> > parent.ref, or if it computed the return value by tracing up the tree.
> > From your response it's clear that it just returns parent.ref.  So in the
> > worst case, every node with a "ref" setting will trace up to <body>
> looking
> > for a parent ref.   That still sounds CPU intensive but maybe not the end
> of
> > the world.
> <snip/>
>
> Correct, thats the worst case. Usually, portion of the bound dijits
> will locate their parent data binding context much closer (than
> <body>).
>
>
> > Note: you probably should be calling dojo.getObject() rather than
> > dojo.eval(), will you ever pass eval() more than a dot separated
> identifier?
> <snap/>
>
> Its a bit of a carte blanche, but the idea is to enable more involved
> expressions if such make sense for the application (as a simple
> example, the ? : ternary operator could be used here).
>
>
> > --------
> > I'm still confused by ref vs. binding.
> <snip/>
>
> There are two different things as follows:
>
> 1. ref:
>
>  * When you think ref, think string. The ref is what enables the dijit
> to locate its initial data binding node (in a StatefulModel).
>  * There are currently two lexical spaces for ref: (a) legal
> JavaScript expression for refs on outermost bound widget that resolves
> to a StatefulModel node, and (b) legal relative model node property
> names on nested bound widgets. These two needn't be the only ones.
>  * The ref is doc'ed as "[const] String", i.e. it is provided once at
> instantiation (either via markup i.e. ref="foo" or
> data-dojo-props="{ref:'foo'}" or programmatically once we have that
> working).
>
> 2. binding:
>
>  * When you think binding, think actual node in StatefulModel. When
> the widget startup is complete, this is what the ref resolves to once
> the relevant ref semantics are applied.
>  * The value space for binding is all StatefulModel nodes.
>  * The widget binding can be updated programmatically per application
> needs. Sidebar: The utility of describing bindings via relative refs
> for nested widgets is that they will automatically resolve themselves
> to new StatefulModel nodes if the parent context (or any ancestor) is
> changed programmatically.
>
> The purpose of this separation is to differentiate the lexical space
> for binding specification from its value space, so more intelligent
> things can be done while transforming between the two spaces during
> page load.
>
>
> >    In one of your test files you
> > have:
> >
> > dijit.byId("view").set("binding", binding);
> >
> > Yet, there's no "binding" attribute declared in _DataBindingMixin.js.
> >
> <snap/>
>
> Right, thats an example of updating the data binding by pointing to a
> different StatefulModel node programmatically. This is how one would
> update bindings beyond page load. A better example is in the "bill
> to/ship to" or order form demo (check out the two buttons).
>
>
> > In one of your test files you have:
> >
> > <input id="taxes" dojoType="dijit.form.NumberTextBox"
> > ref="loanModel.Taxes"/>
> >
> > In that example ref is both the StatefulModel object and the attribute
> > inside of it.   (loanModel.Taxes is a number, right?)
> >
> <snip/>
>
> In above, the ref is the string "loanModel.Taxes" which resolves at
> startup to said node in the application StatefulModel (this node
> reference becomes the "binding"). The node at loanModel.Taxes is not a
> number (its a StatefulModel node). The actual numeric value is here:
> loanModel.Taxes.value but its uncommon to reference it using that
> expression (the bind takes care of all the value and meta-data
> synchronization).
>
>
> > ------
> >
> > Have you thought that users might try to specify ref (or is it binding?)
> as
> > an object rather than as a string?   Something like:
> >       new dijit.form.TextBox({ref: myStatefulModel.employeeName})
> <snap/>
>
> Yes, this will be possible as follows (note the quotes as its a string):
>
>  new dijit.form.TextBox({ref: 'myStatefulModel.employeeName'})
>
>
> > That's not quite right because it will end up as though I had done this:
> >       new dijit.form.TextBox({ref: "John Smith"})
> <snip/>
>
> Its not right for a different reason: myStatefulModel.employeeName
> would evaluate to the model node i.e. its binding, whereas ref is a
> string (please see above).
>
>
> > but anyway it seems like the app should be able to specify the Stateful
> > object being bound as an object rather than as a string name of a global
> > variable.
> >
> <snap/>
>
> Yes, this will be possible as follows (when I'm done, if its not already):
>
>  new dijit.form.TextBox({binding: myStatefulModel.employeeName})
>
>
> > Note that we have this pattern in other widget parameters, for example
> > DateTextBox.value is a Date object, but when you construct a DateTextBox
> or
> > call set("value", ...) you can pass in a string for the value and it gets
> > converted.   In your case it seems like ref (or is it binding?) should be
> an
> > Object, but you allow a string as a parameter to the constructor or
> argument
> > to set("ref", ...) .
> <snip/>
>
> Right, there are similarities.
>
>
> > ----------
> > Here's a test case for you to add, it seems like this should work, but it
> > won't work w/your current code:
> >     myWidget = new myWidget({ref: "foo.bar"})    <--- can't eval ref yet
> > since no parent
> >     myWidget.placeAt(dojo.body());
> >     myWidget.startup()  <--- should set widget's value according to model
> >     myWiget.set("ref", "baz.bam") <-- should reset widget's value
> according
> > to new model
> >
> <snap/>
>
> +1 to adding the above test case with the following change to last line:
>
> +   myWiget.set("ref", "baz.bam")
> -   myWidget.set("binding", baz.bam);
>
> BTW, I'll be looking at programmatic instantiation next (i.e. moving
> data binding mixin function from postCreate() to startup() etc.).
>
> -Rahul
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.dojotoolkit.org/pipermail/dojo-contributors/attachments/20110307/00852ee0/attachment-0001.htm 


More information about the dojo-contributors mailing list