Reputation: 13
I have a problem in Polymer 1.0 related to event propagation within a nested structure of web components. In particular, I am trying to dynamically configure a web component named wc-split
by means of a collection of other components named wc-split-rule
located within its local DOM. The following snippet of code shows a correct form of use:
<wc-split-test>
<wc-split>
<wc-split-rule key="{{k1}}" ...></wc-split-rule>
<wc-split-rule key="{{k2}}" ...></wc-split-rule>
<wc-split-rule key="{{k3}}" ...></wc-split-rule>
</wc-split>
</wc-split-test>
As it can be seen in the previous example, the aim is to provide to the wc-split
component the values on key
attributes within each wc-split-rule
component. As we need dynamic reconfiguration capabilities, the architectural strategy starts by firing an event each time a change in key
attributes is met and those changes are promoted by bubbling up to reach the wc-split
component, which process them.
The followed approach works properly when [1] it is both tested in a pure HTML context with literal values and [2] within a component template with data-bound values. Nevertheless, [3] when it is tested within a component template using literal values, changes are not promoted. It seems that event propagation are ignored or listener defined in wc-split
does not catch the event:
<wc-split-test>
<wc-split> <!-- does not work -->
<wc-split-rule key="k1" ...></wc-split-rule>
<wc-split-rule key="k2" ...></wc-split-rule>
<wc-split-rule key="k3" ...></wc-split-rule>
</wc-split>
</wc-split-test>
The following listing shows implementation of both components [https://goo.gl/OkU9jQ]:
<dom-module id="wc-split-rule">
<script>
Polymer({
is: 'wc-split-rule',
properties: {
key : {
type: String,
reflectToAttribute: true,
notify: true,
value: '',
observer: '_changed'
},
},
_changed: function (){
this.fire('wc-split-rule', {
key : this.key,
});
}
});
</script>
</dom-module>
<dom-module id="wc-split">
<template>
<content></content>
</template>
<script>
Polymer( {
is: 'wc-split',
listeners: {
'wc-split-rule': 'onRule'
},
ready: function(){
...
},
onRule: function (event, context){
... // this is executed in test [1] and [2] NOT in [3]
}
});
</script>
</dom-module>
<dom-module id="wc-split-test">
<template>
<wc-split id="split">
<wc-split-rule key="e1"/>
</wc-split>
</template>
<script>
...
</script>
</dom-module>
Surprisingly, the same code on Polymer 0.5 works properly for each test scenario [https://goo.gl/CHV3JE]:
<polymer-element name="wc-split-rule">
<script>
Polymer('wc-split-rule', {
publish : {
key : '',
},
observe: {
key : '_changed',
},
_changed: function (){
this.fire('wc-split-rule', {
key : this.key,
});
}
});
</script>
</polymer-element>
<polymer-element name="wc-split">
<template>
<div on-wc-split-rule="{{onRule}}">
<content select="wc-split-rule"></content>
</div>
<content></content>
</template>
<script>
Polymer('wc-split', {
ready: function(){
...
},
onRule: function (event, context){
... // this is always executed
}
});
</script>
</polymer-element>
<polymer-element name="wc-split-test">
<template>
<wc-split id="split">
<wc-split-rule key="e1"/>
</wc-split>
</template>
<script>
...
</script>
</polymer-element>
Upvotes: 1
Views: 1125
Reputation: 24119
This boils down to a timing issue. The wc-split-rule
event is firing before your wc-split
element is registered. Therefore, the event is being missed. It's only an issue when the elements are first booted up b/c you have a parent element that's also a custom element. One way around this is to ensure the event fires after the wc-split-rule
is attached:
attached: function() {
this._changed();
},
This works: http://jsbin.com/yixinuhahu/edit?html,output
Upvotes: 1