Polymer - Как вызвать действие для элемента, встроенного в элемент Polymer, со страницы, на которой находится элемент?

Предположим, я создал элемент Polymer, в который были встроены некоторые другие элементы. Затем я помещаю этот элемент на страницу. Из Javascript, который находится на странице, содержащей элемент Polymer, как бы я управлял встроенными элементами, которые находятся внутри элемента Polymer?

Например, что если я создал элемент с именем <treeview>, который внутренне использует <ul>, <li>, а также <paper-checkbox> элементы для создания иерархии дерева. Затем я добавляю этот элемент управления на страницу. Если каждый из <paper-checkbox> элементы внутри <treeview> контроль имеет уникальный идентификатор, как я могу сделать звонок со страницы, чтобы переключить определенный <paper-checkbox> если я знаю уникальный идентификатор элемента, который я хочу переключить?

Я пытался выставить функцию на <treeview> элемент, который я мог бы вызвать, чтобы установить свойство. Например, function toggleTreeviewItem(id), Но когда я пытаюсь вызвать toggleTreeviewItem со страницы, содержащей <treeview> кажется, это никогда не работает. Я думаю, что причина этого заключается в том, что внутри toggleTreeviewItemЯ не могу справиться с <paper-checkbox> элементы управления, которые могут быть встроены во вложенные <template is="dom-repeat"> элементы.

Вот очень упрощенная версия Javascript для <treeview> контроль. Как вы можете видеть в toggleTreeviewItem функции, я попробовал три разных способа получить ручку к конкретному <paper-checkbox> предмет, которым я пытаюсь манипулировать. Никто, казалось, не работал для меня. Я думаю, что я, вероятно, упускаю что-то очевидное.

Polymer({
  is: 'treeview',

  properties: {
    someProperty: {
      type: String,
      value: "Hello Yo!"
    },

  },  // End of Properties

  observers: [
  ],

  ready: function () {
    // does some stuff here...
  },


  toggleTreeviewItem: function(id) {
    console.log('Entered method: toggleTreeviewItem', id);

    try {
      var checkbox = document.getElementById('treeview-item-' + id);
      // var checkbox = document.querySelector("#treeview-item-" + id);
      // var checkbox = Polymer.dom(this.root).querySelector("#treeview-item-" + id);
      console.log('checkbox', checkbox);
      checkbox.checked = !checkbox.checked;

    } catch (ex) {
      console.log('Name:', ex.name);
      console.log('Message:', ex.message);
      console.log('Stack:', ex.stack);
    } finally {
      console.log('Exited method: toggleTreeviewItem');
    }
  }

});

1 ответ

Решение

document.getElementById() а также document.querySelector() (и аналогичные встроенные функции DOM) не могут пробить теневую границу вашего пользовательского элемента, поэтому они не смогут найти внутренний элемент дерева. В вашем случае вы должны использовать this.$$()(Полимерный синтаксический сахар дляthis.querySelector()) вtoggleTreeviewItem():

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',

    _toggleChk2: function() {
      this.toggleTreeviewItem(2);
    },

    toggleTreeviewItem: function(id) {
      const chkbox = this.$$(`#treeview-item-${id}`);
      chkbox.checked = !chkbox.checked;
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.7.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
  <link rel="import" href="paper-checkbox/paper-checkbox.html">
</head>
<body>
  <x-foo></x-foo>
  <script>
    addEventListener('WebComponentsReady', function() {
      var foo = document.querySelector('x-foo');
      foo.toggleTreeviewItem(3);
    });
  </script>

  <dom-module id="x-foo">
    <template>
      <template is="dom-repeat" items="[1,2,3,4]">
        <paper-checkbox id$="treeview-item-[[index]]">Checkbox [[index]]</paper-checkbox>
      </template>
      <button on-tap="_toggleChk2">Toggle Checkbox 2</button>
    </template>
  </dom-module>
</body>

codepen

Другие вопросы по тегам