通知Polymer dom-repeat对本地DOM的更改

时间:2015-06-16 21:06:32

标签: javascript jquery-ui polymer polymer-1.0

我有一个非常基本的自定义元素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,之后模板负责更新视图以反映新数据(剪辑已删除,订单已被删除改变等)。使用jQuery UI Sortable,我可以重新排列播放列表中的剪辑或将它们拖动到新的剪辑,然后在sortstop我通知服务器任何更改,以便它保持同步。这一切似乎都很好,分开。

但是,之后,我的jQuery排序操纵了DOM,模板无法正确更新。据我所知,这是因为模板不知道对其(本地?/ light?)DOM的更改。

例如,让我们说我在播放列表中有三个剪辑[A] [B] [C],我移动第一个,以便它现在最后[B] [C ][一个]。当服务器通知我更改(我自己的)并相应地更新clips时,模板会注意到移位并再次执行。在这个例子中,最终结果是[C] [A] [B]。

到目前为止,我能让它工作的唯一方法是在正确设置之前设置clips = [];。这导致屏幕上的任何tri-clip暂时消失,并迫使Polymer再次创建元素,这首先击败one of the advantages of using a Polymer template(TLDR:聚合物数据绑定使得最小量的必要的变化)。

我遇到this

  

当其中一个模板助手元素更新DOM树时,它会触发dom-change事件。

     

在大多数情况下,您应该通过更改模型数据与创建的DOM进行交互,而不是直接与创建的节点进行交互。对于需要直接访问节点的情况,可以使用dom-change事件。

但是,我不确定如何将它应用到我的情况中。根据我的理解,如果我想在模板触发更改后对节点执行某些操作,我会使用dom-change事件。或者我错了吗?反正是否通知模板已进行更改并且需要相应地更新其模型?我是以错误的方式解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

无论它值多少,我设法提出的解决方法(这不是理想的但修复了我遇到的问题)主要是迭代dom-repeat并评估变化是为了它的孩子(在我的情况下由jQuery排序)。然后执行镜像dom-repeat的{​​{1}}数组上的更改的操作。我使用的是jQuery multisortable plugin所以我不得不考虑未确定的更改量(通常jQuery可排序只会一次更改一个元素)但我认为下面的代码可以很容易地针对这种情况进行优化。在jQuery可排序stop event中,我执行了以下操作:

1)获取索引(index是我的items数组中项目的属性),反映排序之前的位置

dom-repeat

2)查看排序后第一个选定元素的位置(请注意,这与所有子项相关,而前一个循环仅为选定元素)

// 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;
});

3)在// 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 } }); 的{​​{1}}数组(或任何你命名的数组)上进行数组突变以反映DOM更改

dom-repeat

希望这能帮助处于类似情况的任何人

答案 1 :(得分:0)

所以基本上你是手动更改模型,以便Polymer可以与jQuery可排序的更改保持同步?如果可能相关,请查看this示例。不确定它是否适用于jQuery sortable