2015-09-25 54 views
1

我有樹狀列表,可以由用戶更新現有的列表,以匹配新的列表

<ul> 
    <li class="exp"> 
    ... 
    </li> 
    <li> 
    ... 
    </li> 
</ul> 

的內容被摺疊或展開,如果這個名單是懶加載,因爲它可以很大,而且還因爲它可以根據用戶在頁面上做什麼來改變。

延遲加載工作正常,但刪除之後更新它/項目添加到列表中是一個問題

我現在做它的方式是這樣的:

var old_i = 0, 
    new_v = []; 

new_li.each(function(i, li){ 
    new_v.push(node.dataset.value); 

    // new li at the end 
    if(!old_li.get(old_i)){ 
    old_ul.append(li); 
    return; 
    } 

    // existing li 
    if(li.dataset.value == old_li.get(old_i).dataset.value){  
    old_i++; 
    return; 
    } 

    // new li before the end 
    $(li).insertBefore(old_li.get(old_i));   
}); 

// remove non-existing 
old_i.each(function(idx, li){ 
    if(new_v.indexOf(li.dataset.value) < 0) 
    $(li).remove(); 
}); 

但是,當我刪除了最後一個之前的li,最後一個得到了重複。我認爲這個問題在insertBefore附近,但我不知道是什麼原因造成的。

我不知道該如何做的另一件事是重新排序舊列表以匹配新列表的排序。

我知道我可以只更換列表以使事情更容易,但是隨後我將放棄用戶展開 - 摺疊狀態。不僅僅是狀態類,還有內容,因爲ajax響應只返回需要更新的內容,這是活動li(直接子項)的內容。但是,用戶可以擴大兒童或它的孫子,以及那些將失去與一個內容替換

回答

0

我想重複獲得創建類似如下:

如果你的舊名單是:A,B ,c,d和newlist:a,c,d:
您的循環可以正常工作。
但是當你的新列表循環在c時,你的old_li.get()返回b,觸發insertBefore。舊名單現在是a,c,b,c,d。
接下來傳遞,newlist返回d,並返回c(old_i不增加)old_li.get()。這會觸發另一個insertBefore。舊名單現在是a,d,c,b,c,d。

刪除回合後,c值被刪除,留下的新列表成爲a,d,d,c,c。

作爲一個替代方法,我建議:

var old_v; // array with only value strings from old state 
var new_v; // array with only value strings from new state 
var updatedLength=0; 

old_v.reverse().map((itemVal,i) => { 
    if (new_v.indexOf(itemVal) != -1) { 
    // remove item (i) from the old_li in DOM 
    // loop over old_v in reverse order so we don't mess up count 
    } else { 
    UpdatedLength++; 
    } 
} 
new_v.map((itemVal, i) => { 
    if (old_v.indexOf(itemVal) == -1) { 
    if (i >= updatedLength) { 
     // append item (i) from the new_li to DOM at the end 
    } else { 
     // insert item (i) before item at index updatedLength in DOM 
    } 
    updatedLength++; 
    } 
    return itemVal; 
} 

希望這個作品!