Polymer:从组件外部观察更改的属性

问题描述 投票:0回答:2

我有聚合物网络组件。

我现在的问题是,在组件之外,我对数据绑定场景使用淘汰赛。现在我想创建自己的 Knockout 绑定类型,它能够对 Poylmer 对象使用双向绑定。为此,我需要从组件外部订阅属性观察器。这可能吗?什么时候、怎样?

javascript html polymer web-component
2个回答
2
投票

是的,当 Polymer 属性具有

notify: true
时,可以订阅属性更改通知。

属性变更通知事件(notify)

当属性设置为

notify: true
时,只要属性值发生更改,就会触发事件。活动名称是:

_property-name_-changed

其中

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

这些事件由双向数据绑定系统使用。外部脚本也可以直接使用

first-name-changed
来监听事件(如
addEventListener
)。

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

因此,如果您想从外部订阅

<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);
});

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    properties : {
      bar: {
        type: String,
        value: 'Hello world!',
        notify: true
      }
    }
  });
});
<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>

codepen


1
投票

我现在已经解决了以下方法:

        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;
                });
            }
        };
© www.soinside.com 2019 - 2024. All rights reserved.