Basically I am designing an element, say <parent-element>
which does stuff based on what its childNode
s are.
So when I do this
<parent-element>
<div> </div>
<child-element> </child-element>
<paper-button> </paper-button>
</parent-element>
Everything is fine. But when I want to get an event / callback when a new child is added dynamically like so:
Polymer.dom(document.querySelector('parent-element')).appendChild(document.createElement('p'))
How do I get a callback / event triggering a new child?
I've tried all the lifecycle callbacks, created, attached, detached, attributeChanged
Also as per the design of this component, it can have any type of child, a regular HTML Tag, Web Components etc. So the event has to be triggered in my <parent-element>
element and not in any of its children.
@ebidel Mentions in one of his answers (Will post link if I find it), that the answer is MutationObservers.
Does Polymer 1.0 ship with anything that can help me without me resorting to MutationObservers?
If not, which is the most performant way to implement a MutationObserver here? And in which lifecycle callback of the element? I'm sorry I'm completely new to MutationObserver.
Unless your child elements are Polymer custom elements, I'm afraid you've to use MutationObservers. Something like:
<!DOCTYPE html>
<html>
<head>
<title>polymer</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<script src="https://rawgit.com/webcomponents/webcomponentsjs/master/webcomponents-lite.js"></script>
<link rel="import" href="https://rawgit.com/Polymer/polymer/master/polymer.html">
</head>
<body>
<dom-module id="x-test">
<template>
<h1>Mutation Observer Test</h1>
<button on-tap="addTapped">Add Node</button>
<button on-tap="removeTapped">Remove Node</button>
<div id="insertion_point" style="color:red"></div>
<div id="console_log"></div>
</template>
</dom-module>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-test',
properties: {
_mo: {type: Object, value: function () {return {};}}
},
ready: function () {
// first, define the mutation observer.
var t = this;
this._mo = new MutationObserver(function (mutations) {
// because mutations are "collected in intervals"
mutations.forEach(function(mutation) {
t.consoleLog("node added or removed detected");
// add in your tasks when node is added/removed here
});
});
// next, start observing.
this._mo.observe(this.$.insertion_point, {
// configure `childList` to be true to listen to node addition/deletion
childList: true
});
},
consoleLog: function (m) {
var el = document.createElement("div");
el.innerHTML = m;
Polymer.dom(this.$.console_log).appendChild(el);
},
addTapped: function () {
var el = document.createElement("span");
el.innerHTML = "new node!";
Polymer.dom(this.$.insertion_point).appendChild(el);
},
removeTapped: function () {
var el = Polymer.dom(this.$.insertion_point).lastElementChild;
Polymer.dom(this.$.insertion_point).removeChild(el);
}
});
});
</script>
<x-test></x-test>
</body>
</html>
Jsbin: http://jsbin.com/huxuloyobi/edit?html,output
I defined the MO inside the ready
callback because default values and template elements are ready by then.