更新现有列表以匹配新列表

时间:2015-09-25 14:10:27

标签: javascript jquery sync dom-manipulation

我有可以由用户折叠或展开的树状列表

<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(直接子代)的内容。但是用户可以扩展它的子孙,并且那些内容会因为替换而丢失

1 个答案:

答案 0 :(得分:0)

我认为重复项的创建方式如下:

如果您的旧列表是:a,b,c,d和newlist:a,c,d:
你的循环适用于。
但是当您的新列表循环位于c时,您的old_li.get()会返回b,触发insertBefore。 oldlist现在是a,c,b,c,d。
下一遍,newlist返回d,old_li.get()返回c(old_i不递增)。这会触发另一个insertBefore。 oldlist现在是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;
}

希望这有效!