簡體   English   中英

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

[英]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-repeatitems數組上的操作。 我使用的是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-repeatitems數組(或您命名的任何數組)上進行數組更改以反映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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM