I'm just starting to learn Polymer. Here is a generic version of my polymer element:
<polymer-element name="my-element">
<template>
<style>
:host {
position:absolute;
width: 200px;
height: 100px;
background-color: green;
}
</style>
<p>my element</p>
<content id="first-in"></content>
<content id="second-in"></content>
</template>
<script>
Polymer('my-element', {
domReady: function() {
alert(this.children[0].getAttribute('title'));
//this returns the value I want to observe
}
});
</script>
<polymer-element>
The content tags are both being filled with another custom element (again slightly simplified):
<polymer-element name="in-element" attributes="title">
<template>
<style>
...
</style>
<p>{{title}}</p>
</template>
<script>
Polymer('in-element', {
title: 'me'
});
</script>
<polymer-element>
What I want to be able to do is call a function in my-element when the title attribute in (any) in-element (put in the content tag) is changed (by a click event or whatever). I'm not sure how to access this using observe or if I need to use mutationObserver, etc. How is this done/Is it possible?
Native properties like title
are not observable by Polymer's data-binding system (e.g. Object.observe()
[info]). It's generally a good idea to avoid them.
In your example, I've changed title
to mytitle
and published it with reflect: true
so the property value reflects back to the attribute. This way you can completely avoid .getAttribute()
and just check .mytitle
on in-elements. You can also use {{mytitle}}
in bindings.
You can do this through mutation observers [1]. Polymer provides onMutation
to monitor children but you want to monitor attributes of children. For that, you need a pure MO:
ready: function() {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(m) {
if (m.target.localName == 'in-element') { // only care about in-element
console.log(m.attributeName, m.oldValue, m.target.mytitle);
}
});
});
// Observe attribute changes to child elements
observer.observe(this, {
attributes: true,
subtree: true,
attributeOldValue: true
});
}
Demo: http://jsbin.com/doxafewo/1/edit
In domReady()
, I also changed your alert of this.children[0]
to this.$.firstin.getDistributedNodes()[0].mytitle
. Using getDistributedNodes()
is better because you're guaranteed to have the nodes that are actually passing through the <content>
insertion point [2].
For every attribute there is a watcher. So in your case it should be looking like this. Although there are 2 different implementation, one with attribute name as the first argument of the function.
Polymer('in-element', {
title: 'me',
titleChanged: function(oldVal, newVal) {
// do something
}
});
Polymer change watchers