Franz Thomsen
Franz Thomsen

Reputation: 494

In Polymer 1.0 how can I databind to a boolean property of an element?

How can I bind to a boolean property of an element. It seems this

<my-element a-property-of-type-boolean='{{someBoolean}}'></my-element>

does not Work, but I also cant find out how to bind to it when it is exposed like this:

<my-element a-property-of-type-boolean></my-element>

It seems an option is to set the type to Object instead of Boolean, but I am not sure how valid this approach is

Thanks :-)

Upvotes: 5

Views: 4467

Answers (4)

Tanin
Tanin

Reputation: 1933

Add $ at the end of it:

<my-element a-property-of-type-boolean$='[[someBoolean]]'></my-element>

The $ makes it set an attribute (instead of a JS property), and in the case of a boolean (which the docs conveniently doesn't mention) it adds the attribute if someBoolean is true, otherwise removes the attribute if someBoolean is false.

Note, {{}} is for two-way bindings and the docs do state that

Attribute bindings are always one-way, host-to-target.

. Thus a-property-of-type-boolean$='{{someBoolean}}' works the same, but may be confusing because it is not two-way, so using [[]] is nicer.

Upvotes: 1

aemonge
aemonge

Reputation: 2347

As you already figured it out, the behavior of boolean properties has changed in Polymer 1.0 (ref) and now follows the specification of HTML boolean attributes.

You got different solutions to this, but until now I haven't found a clean solution.

As a preface of the solution I'll make a tiny improvement (adding an Id to the problematic element) to your code:

<dom-module id='main-page'>
    <template>
        <paper-button on-tap='tap'>Click me</paper-button>
        <my-element id="myElem" a-property-of-type-boolean></my-element>
        <div>In main page it is <div>{{someBoolean}}</div></div>
    </template>
</dom-module>
  1. (ref) You could listen to notification's and manually add and remove the attribute from your element (ref).

    tap: function() {
      if (this.aPropertyOfTypeBoolean) {
        Polymer.dom(this.$.myElem).removeAttribute('aPropertyOfTypeBoolean');
      } else {
        Polymer.dom(this.$.myElem).setAttribute('aPropertyOfTypeBoolean', true);
      }
    }
    
  2. If you edit the to use a Boolean attribute you can also set it's property as follows: (it wont reflect in the html unless you use reflectToAttribute: true in the property being defined as Boolean):.

    tap: function() {
      this.$.myElem.set('aPropertyOfTypeBoolean', Boolean(this.aPropertyOfTypeBoolean));
    }
    
  3. Or you can either hide your element with hidden or template-if solutions.

<template is="dom-if" if="{{someBoolean}}">
    <my-element a-property-of-type-boolean></my-element>
</template>

<template is="dom-if" if="{{!someBoolean}}">
    <my-element></my-element>
</template>
  1. With hidden

<my-element hidden$="{{someBoolean}}"></my-element>
<my-element a-property-of-type-boolean hidden$="{{!someBoolean}}"></my-element>

Upvotes: 2

Franz Thomsen
Franz Thomsen

Reputation: 494

Ok, sorry about that guys. I have not done my homework. Everything actually seems to be working exactly as I was hoping for and databinding Works fine. Here is the small example that I did to try and prove my point

<!DOCTYPE html>
<html>
<head>
  <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0'>
  <meta name='mobile-web-app-capable' content='yes'>
  <meta name='apple-mobile-web-app-capable' content='yes'>

  <script src='bower_components/webcomponentsjs/webcomponents.js'></script>
  <link rel='import' href='bower_components/polymer/polymer.html'>
</head>
<body>
<dom-module id='my-element'>
    <template>
        <div>In my element it is <div>{{aPropertyOfTypeBoolean}}</div></div>
    </template>
</dom-module>
<script>
    Polymer({
        is: 'my-element',

        properties: {
            aPropertyOfTypeBoolean: {
                type: Boolean,
                value: false,
            }
        }
    });
</script>                               

<dom-module id='main-page'>
    <template>
        <paper-button on-tap='tap'>Click me</paper-button>
        <my-element a-property-of-type-boolean='{{someBoolean}}'></my-element>
        <div>In main page it is <div>{{someBoolean}}</div></div>
    </template>
</dom-module>
<script>
    Polymer({
        is: 'main-page',

        properties: {
            someBoolean: {
                type: Boolean,
                value: false
            }
        },

        tap: function(){
            this.someBoolean = !this.someBoolean;
        }
    });
</script>

<main-page></main-page>

Upvotes: 1

Granze
Granze

Reputation: 517

If you put an attribute on your element, the related property it will always be true. For example in:

<my-element a-property-of-type-boolean='false'></my-element>

a-property-of-type-boolean is true.

So, if you you want to use a Boolean property on your element, I suggest to declare the property with the default value of false and then, if you need to change the value to true, you can add the attribute on you element.

Your Polymer prototype:

Polymer({
  is: 'my-element',
  properties: {
    aPropertyOfTypeBoolean: {
      type: Boolean,
      value: false
    }
  }
});

Your element:

<my-element a-property-of-type-boolean></my-element>

Upvotes: 4

Related Questions