4

I am familiar with bindings with curly braces, like {{variable}}, from Polymer 0.5.

However, in examples and code snippets for the release version of Polymer, I've begun to notice bindings with square brackets, such as [[variable]], as well.

Does {{variable}} mean something different now, or is it the same and [[variable]] is just an addition? What is the difference between binding to [[variable]] and {{variable}} in Polymer?

Adaline Simonian
  • 4,596
  • 2
  • 24
  • 35

1 Answers1

6

Just as you've noticed, there are now two different syntaxes for data-binding, which have different purposes:

  • {{variable}} indicates that you would like Polymer to automatically detect whether or not the binding should be one-way or two-way.
  • [[variable]] indicates that you want the binding to one-way only.

Why the change?

Polymer 1.x differs from older versions is that bindings are now one-way by default, much unlike 0.5, where they were always two-way.

In other words, if you write

<my-element some-property="{{myVariable}}"></my-element>

then by default, when

  • myVariable is changed, Polymer updates the binding, and thus updates my-element's someProperty.
  • someProperty is changed, Polymer does not update the binding to myVariable.

This is always the case unless you set notify:true on the property inside my-element:

Polymer({
  is: 'my-element',
  properties: {
    someProperty: {
      notify: true,
      ...

With notify: true, the binding is now two-way, so when

  • myVariable is changed, Polymer updates the binding to someProperty.
  • someProperty is changed, Polymer also updates the binding to myVariable.

This behaviour (when using notify: true) used to be default in 0.5; now you must ask for it explicitly.

When to use [[variable]]

There's no technical reason why you must use [[variable]], because Polymer will automatically detect whether bindings are one or two-way with {{variable}}. So why would you use it?

Let's say you're working in a large project, and you know that based on the way that data flows in a particular page/element, a certain property should never be changed by the element it is being bound to, for example in the case of an element which functionally serves a purpose as a label:

<display-data source-data="{{data}}"></display-data>
...
<data-editor source-data="{{data}}"></data-editor>

Everything looks good! The data property is bound to both the display-data element and data-editor elements, and will be automatically shared between them. (In this example, assume display-data's sole purpose is to preview the data that it is bound to.)

One day, you or someone else is editing display-data, and you forget about the situation in which it is being used in above. For an entirely different use-case, you or the other developer would like display-data to also format or otherwise modify the data it is given and push it back towards any other elements that may be bound to it. You/they edit display-data as such:

  • Add notify: true to sourceData, to allow two-way data-binding.
  • Add code into display-data which modifies the sourceData property.

This works great for all the pages that needed this functionality. But on the page mentioned before, this was not intended and ends up garbling the data that data-editor sees!

This problem would have been avoided had:

  • The dev team communicated better and had been more considerate of where elements are being used,
  • and/or [[data]] was used instead of {{data}} in the page/element in question.

With

<display-data source-data="[[data]]"></display-data>
...
<data-editor source-data="{{data}}"></data-editor>

data-editor can change data, but display-data will only ever be able to read data, and won't be able to change its value when it changes the value of its sourceData property, even when notify: true is set on sourceData.

Therefore, it could potentially be a good idea to:

  • Use [[variable]] whenever you need to bind to variable. This way, you enforce the direction through which data should flow in your element/page/application.
  • Use {{variable}} whenever you know that the binding must be two-way.

According to the documentation,

To make your code more easier to read, you may want to use the [[property]] form by default, and only use {{property}} for two-way bindings.

This being said, however, it ultimately comes down to a matter of choice. If you want to forego the use of [[variable]], no one is stopping you and you will not start any fires.

Adaline Simonian
  • 4,596
  • 2
  • 24
  • 35