如何从JS访问Polymer函数

时间:2016-07-04 16:22:29

标签: polymer interact.js

很抱歉,如果这有点乱码,我不知道如何提出这个问题。

我要做的是保持DOM与localStorage值同步,并使用interact.js鼠标事件更新localStorage值。

目前,我能够正确设置localStorage值,但是在更新DOM时遇到了问题。

我目前的版本在Polymer框架内,所以我在选择shadow DOM内容时遇到了麻烦。

DOM树看起来像

PARENT-ELEMENT
  # SHADOW ROOT
    EL
    EL
    DIV
      CUSTOM ELEMENT
    EL
    EL

以下是我未能解决问题的一些方法。 Custom Element是纯JS的,因为我不确定如何在Polymer中正确地包装interact.js函数:

  1. 我尝试直接从纯JS中的自定义元素访问PARENT-ELEMENT的影子DOM。
  2.   var shadowDOMNode = document.querySelector('PARENT-ELEMENT');
      var dom_object_1 = shadowDOMNode.querySelector('#dom_object_1');
      dom_object_1.innerHTML = localStorage.dom_object_1;
    
    1. 我尝试从PARENT Polymer元素中选择一个帮助程序updateDOM()函数,并直接从Custom Element的setter中运行它。
    2. if (event.dy > 0) {
          this.$$('PARENT-ELEMENT').updateDOM();
      }
      

      也许我完全采取了错误的方法,但我还没有能够在使用本机Polymer函数时找到interact.js的类似物。

      我希望这个问题足够明确......

2 个答案:

答案 0 :(得分:1)

如果我们忽略问题的interact.js部分并专注于Polymer,你可以解决这个问题,而不必将它们联系起来。

要使用Polymer绑定到localStorage值,请使用<iron-localstorage>元素。在以下示例中,名为localStorage的{​​{1}}值已加载并存储到名为flavor_1_amount的属性中。如果_flavor1Amount中不存在该值或为空,则localStorage元素将触发事件(<iron-localstorage>),这允许您绑定到回调(例如,初始化它)

iron-localstorage-load-empty

在同一元素中,您可以为用户提供更新<iron-localstorage name="flavor_1_amount" value="{{_flavor1Amount}}" use-raw on-iron-localstorage-load-empty="_initFlavor1Amount"> </iron-localstorage> 值的输入。

localStorage

您可以使用<iron-localstorage>.reload()来保持数据绑定的同步,假设可以在外部进行更改。

有关完整演示,请参阅此codepen。检查Chrome DevTools中的<paper-input label="Flavor Amount (mL)" value="{{_flavor1Amount}}"></paper-input>

enter image description here

答案 1 :(得分:0)

一般来说,如果它是一个数组,你应该使用this.set()或任何array mutation methods,以便正确地通知

由于你想要从元素本身外部执行此更新,当然,我建议这样做:

  • 从您的元素中展示一些方法,您可以使用这些方法从元素外部添加/删除/更改属性值。

  • 这些方法将在内部使用适当的渠道进行更改。

一个示例(您可以调用addItem()来添加元素外部的项目):

<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">

<dom-module id="x-example">
  <template>
    <template is="dom-repeat" items="[[data]]">
      <div>{{item.name}}</div>
    </template>
  </template>
  
  <script>
  HTMLImports.whenReady(function() {
    "use strict";

    Polymer({

      is: "x-example",
      properties: {
      	data: {
          type: Array,
          value: [
            {name: "One"},
            {name: "Two"},
            {name: "Three"}
          ]
        }
      },
      
      // Exposed publicly, grab the element and use this method
      // to add your item
      addItem: function(item) {
        this.push("data", item);  
      }

    });
  });
  </script>
</dom-module>

<x-example id="x-example-elem"></x-example>

<script>
  setTimeout(function() {
    // simply 'grab' the element and use the 
    // `addItem()` method you exposed publicly 
    // to add items to it.
    document.querySelector("#x-example-elem").addItem({name: "Four"});
  }, 2500);

</script>

重要:话虽这么说,这不是“聚合”的做事方式,因为这种编程风格势在必行,与Polymer的风格相比更具说明性。最通用的解决方案是将interact.js功能包装在元素本身中,并使用2个元素之间的数据绑定来执行更改。