[英]Inform Polymer dom-repeat of changes to local DOM
我有一個非常基本的自定義元素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
,之后模板將負責更新視圖以反映新數據(刪除clips
,更改訂單等)。 使用jQuery UI Sortable,我可以重新排列播放列表中的剪輯或將它們拖到新的剪輯中,並在sortstop
任何更改通知服務器,以使其保持同步。 一切似乎都可以單獨工作。
但是, 在通過jQuery排序操作DOM 之后 ,模板無法正確更新。 據我所知,這是因為模板不知道對其(本地?/ light?)DOM的那些更改。
例如,假設我在一個播放列表中有三個剪輯[A] [B] [C],然后移動第一個剪輯,使它現在是最后一個[B] [C] [A]。 當服務器通知我更改(我自己的更改)並相應地更新clips
,模板會注意到該偏移並再次執行 。 在此示例中,最終結果是[C] [A] [B]。
到目前為止,使它起作用的唯一方法是設置clips = [];
正確設置之前。 這會導致屏幕上的任何tri-clip
暫時消失,並迫使Polymer重新創建所有元素,從而失去了首先使用Polymer模板的優勢之一 (TLDR:聚合物數據綁定使最小化)必要的更改量)。
我遇到了這個 :
當模板幫助器元素之一更新DOM樹時,它將觸發dom-change事件。
在大多數情況下,應該通過更改模型數據來與創建的DOM進行交互,而不是直接與創建的節點進行交互。 對於需要直接訪問節點的情況,可以使用dom-change事件。
但是,我不確定如何將其應用於我的情況。 據我了解,如果我想在模板觸發更改后對節點執行某些操作,則將使用dom-change
事件。 還是我錯了? 無論如何,有沒有通知模板進行了更改並且需要相應地更新其模型? 我會以錯誤的方式處理嗎?
無論如何,我設法提出的解決方法(雖然不理想,但解決了我遇到的問題)本質上是要對dom-repeat
進行迭代並評估對其子代所做的更改(在我的情況下是通過jQuery可排序的)。 然后執行將這些更改反映在dom-repeat
的items
數組上的操作。 我使用的是jQuery可排序的jQuery插件,因此我不得不考慮未確定的更改量(通常jQuery可排序的一次只能更改一個元素),但是我認為下面的代碼可以輕松地針對這種情況進行優化。 在jQuery sortable stop事件中 ,我執行了以下操作:
1)獲取索引(索引是我的dom-repeat
數組中各項的屬性),反映排序前 dom元素的位置
// 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)查看排序后第一個選定元素的位置(請注意,這與所有子元素有關,而前一個循環僅是選定元素)
// 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)在dom-repeat
的items
數組(或您命名的任何數組)上進行數組更改以反映DOM更改
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]);
}
}
希望能對類似情況的人有所幫助
因此,基本上,您是在手動更改模型,以便Polymer可以與jQuery可排序所做的更改保持同步? 檢查此示例是否可能相關。 不確定是否可以與jQuery sortable一起使用
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.