【问题标题】:Polymer: How to watch for change in <content> propertiesPolymer:如何观察 <content> 属性的变化
【发布时间】:2014-07-11 14:03:17
【问题描述】:

我刚刚开始学习 Polymer。这是我的聚合物元素的通用版本:

<polymer-element name="my-element">
    <template>
        <style>
        :host {
            position:absolute;
            width: 200px;
            height: 100px;
            background-color: green;
        }
        </style>
        <p>my element</p>
        <content id="first-in"></content>
        <content id="second-in"></content>
    </template>
    <script>
    Polymer('my-element', {
        domReady: function() {
            alert(this.children[0].getAttribute('title')); 
            //this returns the value I want to observe
        }
    });
    </script>
<polymer-element>

内容标签都被另一个自定义元素填充(再次稍微简化):

<polymer-element name="in-element" attributes="title">
    <template>
        <style>
        ...
        </style>
        <p>{{title}}</p>
    </template>
    <script>
    Polymer('in-element', {
        title: 'me'
    });
    </script>
<polymer-element>

当(任何)元素内(放入内容标签)中的标题属性(通过点击事件或其他)更改时,我想要做的是在我的元素中调用一个函数。我不确定如何使用observe 访问它,或者我是否需要使用mutationObserver 等。这是如何完成的/有可能吗?

【问题讨论】:

    标签: javascript html polymer web-component content-tag


    【解决方案1】:

    Polymer 的数据绑定系统无法观察到像 title 这样的原生属性(例如 Object.observe() [info])。 避免它们通常是个好主意。

    在您的示例中,我已将 title 更改为 mytitle 并使用 reflect: true 发布它,因此属性值会反映回属性。这样你就可以完全避免.getAttribute(),只需检查.mytitle 元素。你也可以在绑定中使用{{mytitle}}

    您可以通过突变观察者 [1] 来做到这一点。 Polymer 提供onMutation 来监控孩子,但你想监控孩子的属性。为此,您需要一个纯粹的 MO:

    ready: function() {
      var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(m) {
          if (m.target.localName == 'in-element') { // only care about in-element
            console.log(m.attributeName, m.oldValue, m.target.mytitle);
          }
        });  
      });
      // Observe attribute changes to child elements
      observer.observe(this, {
        attributes: true,
        subtree: true,
        attributeOldValue: true
      }); 
    }
    

    演示:http://jsbin.com/doxafewo/1/edit

    domReady(),我也把你的this.children[0]的提醒改成了this.$.firstin.getDistributedNodes()[0].mytitle。使用getDistributedNodes() 会更好,因为您可以保证拥有实际通过&lt;content&gt; 插入点[2] 的节点。

    【讨论】:

    • 谢谢,这很好用!虽然,我想在 mutation.forEach() 期间在我的元素中调用一个自定义函数(称为“重新计算”)。函数调用在 ready() 中有效,但在 forEach() 期间无效。我该怎么做?
    • 听起来你忘了bind(this)mutations.forEach(function(m) {...}.bind(this));
    • 你对绑定是正确的。这解决了问题并允许我调用正确的函数。但是在函数中我不能再使用getDistributedNodes()。但是,我可以使用this.children 来获得我想要的值。这是this.children的正确用法吗?
    • 我得看看你在做什么,但这可能是另一种情况,你需要在函数上使用.bind(this)。 JS 作用域很有趣!
    【解决方案2】:

    每个属性都有一个观察者。所以在你的情况下,它应该看起来像这样。虽然有 2 种不同的实现,一个以属性名称作为函数的第一个参数。

    Polymer('in-element', {
        title: 'me',
        titleChanged: function(oldVal, newVal) {
            // do something
        }
    });
    

    Polymer change watchers

    【讨论】:

    • title 这样的原生属性不能被 Polymer 的数据绑定系统观察到(例如 Object.observe())。见github.com/Polymer/docs/issues/90#issuecomment-19845774
    • 应该是来自 Polymer 错误处理系统对此类事情的更好警告(不支持属性)。我认为 id 是另一个。
    猜你喜欢
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    相关资源
    最近更新 更多