TemplateBinding: assignable/bindable ref, clear, bindingDelegate, etc..

492 views
Skip to first unread message

Rafael Weinstein

unread,
Feb 3, 2014, 6:11:08 PM2/3/14
to polymer-dev
Hi all,

If you don't care about design minutiae of databinding, you can stop reading now.

I've been thinking about the semantics of ref and assigning the bindingDelegate and there are a few problems with our current behavior

-Assigning a different binding delegate once a template has begun producing instances affects only future (not present) instances, resulting, potentially, in instances coexisting with different binding delegates.

-Ref (as in <template ref>) is resolved every time an instance is produced. This is potentially wasteful

-There's no way to "clear" a template (remove all instances and stop it from operating)

Also, https://github.com/Polymer/TemplateBinding/issues/151 shows that binding to ref dynamically is potentially useful.

As such, I propose some semantic/API changes as well as a design invariant:

Invariant:

-At any given time a template should have instances which are more or less "of the same mold" (e.g. produced from the same template.content and bindingDelegate).

Semantic/API changes:

-template should have a clear() API, which removes all instances, essentially resetting the template's internal state (clearing the model, bindingDelegate, etc...).

-ref should be resolved once, the first time a template produces an instance.

-assigning to ref causes the template to remove its instances and reproduce new ones using the newly referenced content (by extension binding to ref this to be declarative).

-assigning to bindingDelegate once the template model is assigned throws an Error. I realize this isn't very DOM-y, but the alternative which ensures the invariant is to act like ref, removing all instances and starting over. In the case of bindingDelegate, it's less clear there are use cases which drive this and simple ordering mistakes (assigning the bindingDelegate after the model) potentially create a very expensive no-op which is easy not to notice.

I'm going start working on patches for the above, but I'm interested in opinions.

John Messerly

unread,
Feb 3, 2014, 6:35:35 PM2/3/14
to Rafael Weinstein, polymer-dev
fwiw, this sounds reasonable to me, a few questions though...

On Mon, Feb 3, 2014 at 3:11 PM, Rafael Weinstein <raf...@google.com> wrote:
Hi all,

If you don't care about design minutiae of databinding, you can stop reading now.

I've been thinking about the semantics of ref and assigning the bindingDelegate and there are a few problems with our current behavior

-Assigning a different binding delegate once a template has begun producing instances affects only future (not present) instances, resulting, potentially, in instances coexisting with different binding delegates.

-Ref (as in <template ref>) is resolved every time an instance is produced. This is potentially wasteful

-There's no way to "clear" a template (remove all instances and stop it from operating)

Is "clear" different from assigning `model = undefined`? Should it be called "clearModel" or something like that, to indicate that it isn't clearing the template content?
 

Also, https://github.com/Polymer/TemplateBinding/issues/151 shows that binding to ref dynamically is potentially useful.

As such, I propose some semantic/API changes as well as a design invariant:

Invariant:

-At any given time a template should have instances which are more or less "of the same mold" (e.g. produced from the same template.content and bindingDelegate).

Semantic/API changes:

-template should have a clear() API, which removes all instances, essentially resetting the template's internal state (clearing the model, bindingDelegate, etc...).

Most (all?) templates in Polymer set the model using createInstance. Does "clear" change anything for that case? (Probably doesn't change anything, since createInstance doesn't support if/bind/repeat on the template it is called on and it doesn't have an associated TemplateIterator.)
 
-ref should be resolved once, the first time a template produces an instance.

-assigning to ref causes the template to remove its instances and reproduce new ones using the newly referenced content (by extension binding to ref this to be declarative). 

Does assigning ref have a similar issue to bindingDelegate, where assigning it out-of-order causes something expensive to happen? I guess the difference is: we assume most of the time "ref" will be initialized from an attribute (either fixed value or via data binding), whereas bindingDelegate must be set programmatically.
 
-assigning to bindingDelegate once the template model is assigned throws an Error. I realize this isn't very DOM-y, but the alternative which ensures the invariant is to act like ref, removing all instances and starting over. In the case of bindingDelegate, it's less clear there are use cases which drive this and simple ordering mistakes (assigning the bindingDelegate after the model) potentially create a very expensive no-op which is easy not to notice.

Hmmm, since you can set bindingDelegate anytime before you end your microtask, I'm not sure it would happen much in practice. OTOH, I can't really think of a valid use case for changing the bindingDelegate after the fact, without just calling "clear".


Rafael Weinstein

unread,
Feb 3, 2014, 7:23:27 PM2/3/14
to John Messerly, polymer-dev
On Mon, Feb 3, 2014 at 3:35 PM, John Messerly <jmes...@google.com> wrote:
fwiw, this sounds reasonable to me, a few questions though...

On Mon, Feb 3, 2014 at 3:11 PM, Rafael Weinstein <raf...@google.com> wrote:
Hi all,

If you don't care about design minutiae of databinding, you can stop reading now.

I've been thinking about the semantics of ref and assigning the bindingDelegate and there are a few problems with our current behavior

-Assigning a different binding delegate once a template has begun producing instances affects only future (not present) instances, resulting, potentially, in instances coexisting with different binding delegates.

-Ref (as in <template ref>) is resolved every time an instance is produced. This is potentially wasteful

-There's no way to "clear" a template (remove all instances and stop it from operating)

Is "clear" different from assigning `model = undefined`? Should it be called "clearModel" or something like that, to indicate that it isn't clearing the template content?

model = undefined doesn't remove instances in the case of <template bind>. I don't feel strongly about naming, but I mildly prefer the brevity of "clear". Another option is "reset". Any other opinions?
 
 

Also, https://github.com/Polymer/TemplateBinding/issues/151 shows that binding to ref dynamically is potentially useful.

As such, I propose some semantic/API changes as well as a design invariant:

Invariant:

-At any given time a template should have instances which are more or less "of the same mold" (e.g. produced from the same template.content and bindingDelegate).

Semantic/API changes:

-template should have a clear() API, which removes all instances, essentially resetting the template's internal state (clearing the model, bindingDelegate, etc...).

Most (all?) templates in Polymer set the model using createInstance. Does "clear" change anything for that case? (Probably doesn't change anything, since createInstance doesn't support if/bind/repeat on the template it is called on and it doesn't have an associated TemplateIterator.)

No. In polymer-land, the issue is any subtemplates within that instance. Those essentially have model implicitly set on them, so calling clear() would remove their instances.
 
 
-ref should be resolved once, the first time a template produces an instance.

-assigning to ref causes the template to remove its instances and reproduce new ones using the newly referenced content (by extension binding to ref this to be declarative). 

Does assigning ref have a similar issue to bindingDelegate, where assigning it out-of-order causes something expensive to happen? I guess the difference is: we assume most of the time "ref" will be initialized from an attribute (either fixed value or via data binding), whereas bindingDelegate must be set programmatically.
 
-assigning to bindingDelegate once the template model is assigned throws an Error. I realize this isn't very DOM-y, but the alternative which ensures the invariant is to act like ref, removing all instances and starting over. In the case of bindingDelegate, it's less clear there are use cases which drive this and simple ordering mistakes (assigning the bindingDelegate after the model) potentially create a very expensive no-op which is easy not to notice.

Hmmm, since you can set bindingDelegate anytime before you end your microtask, I'm not sure it would happen much in practice. OTOH, I can't really think of a valid use case for changing the bindingDelegate after the fact, without just calling "clear".

ref and bindingDelegate are similar conceptually. 

I think main difference is that assigning ref imperatively is likely to be extremely rare and changing it at run-time (i.e. binding to it) is potentially useful -- while assigning to bindingDelegate will be common and changing it dynamically is less obviously useful.

Reply all
Reply to author
Forward
0 new messages