Reputation: 16102
I want to databind to an object's sub-property.
I expect to see my output change in response to selecting different menu items. But instead, I see no response in the output.
To recreate the problem, follow these steps.
What code makes Computed respond to changes in the sub-property ob.selected
?
<!doctype html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="paper-menu/paper-menu.html" rel="import">
<link href="paper-item/paper-item.html" rel="import">
</head>
<body>
<x-element></x-element>
<dom-module id="x-element">
<template>
<style>
iron-selector > * {
padding: 8px;
}
.iron-selected {
background-color: blue;
color: white;
}
</style>
<br><br>
<paper-menu multi attr-for-selected="name" selected-values="{{ob.selected}}">
<paper-item name="foo" >Foo</paper-item>
<paper-item name="bar" >Bar</paper-item>
<paper-item name="baz" >Baz</paper-item>
<paper-item name="qux" >Qux</paper-item>
<paper-item name="quux">Quux</paper-item>
</paper-menu>
<p>
<strong>Dom-repeat</strong>:
<template is="dom-repeat" items="{{ob.selected}}">
<span>[[item]] </span>
</template>
</p>
<p><strong>Computed</strong>: {{str}}</p>
</template>
<script>
Polymer({
is: 'x-element',
properties: {
ob: {
type: Object,
value: function() {
return {
selected: ['bar', 'qux'],
}
}
},
str: {
type: String,
computed: '_computeStr(ob)',
}
},
_computeStr: function(temp) { // Doesn't respond to changes in temp.selected
return temp.selected.join(', ');
},
});
</script>
</dom-module>
</body>
Upvotes: 0
Views: 129
Reputation: 11027
It's important to understand object identity. Today, Polymer considers the value of an Object to be it's identity. If x == 2, and I set x=4, x has changed value. If ob = {foo:3}, and I set ob.foo = 4, ob has not changed value (it's identity hasn't changed) and this change will not trigger an observation of ob
.
Instead, we can observe ob.foo
directly, or all subproperties of ob via ob.*
or, if it's an array, observe the length of ob (ob.length
).
Something like this will work, for example:
str: {
type: String,
computed: '_computeStr(ob, ob.*)',
}
},
_computeStr: function(temp, info) {
return temp.selected.join(', ');
},
this works because I've asked to be notified if subproperties of ob change ... this is ob.*
The info
returned for an observation of ob.*
has information on it about what happened to ob
.
Upvotes: 4