我有聚合物网络组件。
我现在的问题是,在组件之外,我对数据绑定场景使用淘汰赛。现在我想创建自己的 Knockout 绑定类型,它能够对 Poylmer 对象使用双向绑定。为此,我需要从组件外部订阅属性观察器。这可能吗?什么时候、怎样?
是的,当 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>
我现在已经解决了以下方法:
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;
});
}
};