简体   繁体   中英

Polymer data-binding: how to access data in nested template?

I want to implement a page containing a paper-tabs, with each tab showing a list of items according to the name initial. I wonder what is the best way for data-binding.

Also I have some trouble to access the data in the nested template. When I tap different tabs, it is not working as I expect.

Here is the simplified code:

//page
<paper-tabs selected="{{tab}}">
  <template repeat="{{inital in pagination}}">
    <paper-tab name="{{initial}}">
      {{initial}}
    </paper-tab>
  </template>
</paper-tabs>

<items-field
  tab="{{tab}}"
  items="{{items}}">
</items-field>


//items-field
<polymer-element name="items-field" attributes="tab items">
  <template>
    <h2>h2 {{tab}}</h2>
    <div>some other stuffs</div>
    <template bind="{{items}}">
      <h3>h3 {{tab}}</h3> <-- {{tab}} is undefined
      <item-list
        initial="{{tab}}"
      </item-list>
    </template>
  </template>
  <script>
  Polymer({
    tab: 'A'
  )}
  </script>
</polymer-element>


//item-list
<polymer-element name="items-list" attributes="initial">
  <template>
    <template repeat="{{item in items}}">
      <item
        hidden?="{{toHide(initial, item.name)}}">
      </item>
    </template>
  </template>

  <script>
    Polymer({
      ready: function () {
        this.items = this.templateInstance.model;
        console.log(this.initial); // <-- undefined
      },

      toHide: function (initial, name) {
        if (initial === undefined ||
          initial === name.charAt(0)) {
          return false;
        }

        return true;
      }
    });
    </script>
</polymer-element>

I think the main issue you're running into is messing up your binding scopes.

This bit here:

<template bind="{{items}}">
  <h3>h3 {{tab}}</h3> <-- {{tab}} is undefined
  <item-list initial="{{tab}}"
  </item-list>
</template>

By binding to items , you've created a new scope specific to the items object. So looking for {{tab}} within that scope, is like asking for items.tab which is not what you want. You can jump back to the parent scope in certain situations using named scopes, but not in this case. Explained more here . (Also, your code says item-list when it should be item s -list).

So I solved this in a different way by omitting the bind to items and just passing the items collection down to the children.

<template is="auto-binding" id="app">

  <paper-tabs selected="{{tab}}" valueattr="name">
    <template repeat="{{initial in pagination}}">
      <paper-tab name="{{initial}}">
        {{initial}}
      </paper-tab>
    </template>
  </paper-tabs>

  <items-field tab="{{tab}}"
               items="{{items}}">
  </items-field>

</template>

<script>
  var app = document.querySelector('#app');
  app.pagination = ['A', 'B', 'C'];
  app.tab = 'B';
  app.items = [{name: 'Alpha'}, {name: 'Beta'}, {name: 'Charlie'}];
</script>

<polymer-element name="items-field" attributes="tab items">
  <template>
    <h2>h2 {{t}}</h2>
    <div>some other stuffs</div>
    <h3>h3 {{tab}}</h3>
    <items-list initial="{{tab}}" items="{{items}}"></items-list>
  </template>
  <script>
    Polymer({
      tab: 'A'
    });
  </script>
</polymer-element>

<polymer-element name="items-list" attributes="initial items">
  <template>
    <div>{{initial}}</div>
    <template repeat="{{item in items}}">
      <div hidden?="{{toHide(initial, item.name)}}">
        {{item.name}}
      </div>
    </template>
  </template>

  <script>
    Polymer({

      ready: function () {

      },

      toHide: function (initial, name) {
        if (initial === undefined ||
            initial === name.charAt(0)) {
          return false;
        }

        return true;
      }
    });
  </script>
</polymer-element>

JSBin example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM