I have a pretty basic custom element
tri-playlist
tri-clip
<dom-module id="tri-playlist">
<template>
<template is="dom-repeat" items={{clips}}>
<tri-clip clip-num={{item.clipNum}}></tri-clip>
</template>
</template>
</dom-module>
clips
clips
sortstop
clips
clips = [];
tri-clip
When one of the template helper elements updates the DOM tree, it fires a dom-change event.
In most cases, you should interact with the created DOM by changing the model data, not by interacting directly with the created nodes. For those cases where you need to access the nodes directly, you can use the dom-change event.
dom-change
For whatever it's worth, the work-around I managed to come up with (which isn't ideal but fixes the issues I was running in to) is essentially to iterate over the dom-repeat
and assess the changes that were made to its children (in my case by jQuery sortable). Then carry out operations that mirror those changes on dom-repeat
's items
array. I was using a jQuery multisortable plugin so I had to account for an undetermined amount of changes (where as normally jQuery sortable will only ever change one element at a time) but I figure the code below could easily be optimized for such situations. In the jQuery sortable stop event, I did the following:
1 ) Get the indices (index was a property of the items in my dom-repeat
array) reflecting the positions of dom elements before sorting
// get indices of selected elements that presumably changed
var target = event.target,
toRearr = [],
firstSelected = null;
$( target ).children( '.selected' ).each( function() {
toRearr.push(this.index);
// keep reference of first selected for re-ordering start point
if (firstSelected === null) firstSelected = this;
});
2) See where first selected element is after sorting (note that this is in relation to all of the children, whereas the previous loop was only selected elements)
// find the index of where we need to 'paste' the elements
var toPaste = -1;
$( target ).children( 'selector' ).each( function( index ) {
if (this === firstSelected) {
if (firstSelected.index > index) { // elements were moved to the left
toPaste = index;
return false; // breaks out of $.each loop
}
else if (firstSelected.index < index){ // elements were moved to the right
toPaste = index + toRearr.length;
return false; // breaks out of $.each loop
}
//else no elements were changed
}
});
3) Make array mutations on dom-repeat
's items
array (or whatever you've named it) to reflect DOM changes
if (toPaste !== -1) { // meaning its children were indeed rearranged
// inform Polymer of the change
var tempPaste = toPaste;
for (var i = toRearr.length - 1; i >= 0; i--) { // start from end to preserve order
// we're moving an item to the right of our 'paste' index, so decrease
// tempPaste by 1 so it stays consistent
if (tempPaste > toRearr[i]) tempPaste--;
// move element from old index to new index, using two array splices
// that essentially remove and reinsert the element in the array
target.splice('items', tempPaste, 0, target.splice('items', toRearr[i], 1)[0]);
}
}
Hopefully that'll help anyone in a similar situation