Polymer:从Component外部观察更改的Property

时间:2016-10-27 17:36:34

标签: javascript html5 polymer web-component

我是Polymer Webcomponent。

我现在的问题是,在组件之外我使用了淘汰数据绑定方案。现在我想创建自己的Knockout绑定类型,它能够使用两个与Poylmer对象绑定的绑定。为此,我需要从组件外部订阅Property观察者。这可能吗?什么时候,怎么样?

2 个答案:

答案 0 :(得分:2)

是的,当Polymer属性具有notify: true时,可以订阅属性更改通知。

  

Property change notification events (notify)

     

当属性设置为notify: true时,只要属性值发生更改,就会触发事件。事件名称为:

_property-name_-changed
     

其中 property-name 是属性名称的破折号版本。例如,对this.firstName的更改会触发first-name-changed

     

这些事件由双向数据绑定系统使用。外部脚本还可以使用first-name-changed直接侦听事件(例如addEventListener)。

     

有关属性更改通知和数据系统的更多信息,请参阅Data flow

因此,如果您想在外部订阅<x-foo>.bar以与Knockout互操作,则可以addEventListener()用于bar-changed事件:

var foo = document.querySelector('x-foo');
foo.addEventListener('bar-changed', function(e) {
  console.log('new bar:', e.detail.value);
});

&#13;
&#13;
HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    properties : {
      bar: {
        type: String,
        value: 'Hello world!',
        notify: true
      }
    }
  });
});
&#13;
<head>
  <base href="https://polygit.org/polymer+1.11.3/webcomponents+webcomponents+:v0/components/">
  <script src="webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <x-foo></x-foo>
  <script>
    window.addEventListener('WebComponentsReady', function() {
      var foo = document.querySelector('x-foo');
      foo.addEventListener('bar-changed', function(e) {
        console.log('new bar:', e.detail.value);
      });
      
      foo.bar = 'hey';
      foo.bar = 'there!';
    });
  </script>

  <dom-module id="x-foo">
    <template>[[bar]]</template>
  </dom-module>
</body>
&#13;
&#13;
&#13;

codepen

答案 1 :(得分:0)

我现在已经解决了以下问题:

        ko.bindingHandlers['polymer'] = {
            'init': function (element, valueAccessor, allBindings) {
                var eventsToHandle = valueAccessor() || {};
                ko.utils.objectForEach(eventsToHandle, function (eventName, value) {
                    if (typeof eventName == "string") {
                        var polymerEvent = eventName.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase() + '-changed';
                        var listener = function(e) {
                            value(e.detail.value);
                        };
                        element.addEventListener(polymerEvent, listener);
                        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                            element.removeEventListener(polymerEvent, listener);
                        });
                    }
                });
            },
            'update': function (element, valueAccessor, allBindings) {
                var value = ko.utils.unwrapObservable(valueAccessor()) || {};
                ko.utils.objectForEach(value, function (attrName, attrValue) {
                    attrValue = ko.utils.unwrapObservable(attrValue);
                    element[attrName] = attrValue;
                });
            }
        };