添加新项目后的 ng2-dragula 显示在顶部

ng2-dragula after adding new item it's getting displayed at the top

我正在使用 ng2-dragula 进行拖放功能。当我在最后拖放第一个元素(或任何元素)然后尝试使用 addNewItem 按钮将新项目添加到数组时,我看到了问题,新项目没有被添加到最后。如果我不将元素放到末尾,新项目将添加到 UI 的末尾。 我希望新项目在任何情况下都显示在底部。任何帮助表示赞赏。 Angular 7 无法重现此问题。我发现 Angular 9

会发生这种情况

JS

export class SampleComponent {

  items = ['Candlestick','Dagger','Revolver','Rope','Pipe','Wrench'];
  constructor(private dragulaService: DragulaService) { 
    dragulaService.createGroup("bag-items", {
      removeOnSpill: false
    });
  }

  public addNewItem() {
    this.items.push('New Item');
  }
}

HTML

<div class="container" [dragula]='"bag-items"' [(dragulaModel)]='items'>
    <div *ngFor="let item of items">{{ item }}</div> 
</div>

您可以尝试在掉落时恢复旧物品位置。

constructor(private dragulaService: DragulaService) {
  this.subscription = this.dragulaService.drop().subscribe(({ name }) => {
    this.dragulaService.find(name).drake.cancel(true);
  });
} 

Forked Stackblitz

说明

Ivy 和 ViewEngine 在特定索引处插入 ViewRef 的方式有些不同。它们依赖于不同的 beforeNode

Ivy always returns ViewContainer host(Comment node)ref 如果我们在末尾添加item:

export function getBeforeNodeForView(viewIndexInContainer: number, lContainer: LContainer): RNode|
    null {
  const nextViewIndex = CONTAINER_HEADER_OFFSET + viewIndexInContainer + 1;
  if (nextViewIndex < lContainer.length) {
    const lView = lContainer[nextViewIndex] as LView;
    const firstTNodeOfView = lView[TVIEW].firstChild;
    if (firstTNodeOfView !== null) {
      return getFirstNativeNode(lView, firstTNodeOfView);
    }
  }

  return lContainer[NATIVE]; <============================= this one
}

ViewEngine returns 最后渲染节点(最后 <li/> 元素)ref

function renderAttachEmbeddedView(
    elementData: ElementData, prevView: ViewData|null, view: ViewData) {
  const prevRenderNode =
      prevView ? renderNode(prevView, prevView.def.lastRenderRootNode!) : elementData.renderElement;
  ...
}

解决方案可能是将拖动的元素恢复到原始容器,这样我们就可以让 built-in ngForOf Angular 指令进行智能差异化。

顺便说一句,Angular material DragDropModule 中使用了相同的技术。它会记住拖动元素的位置,并在我们放下项目后将其插入到 DOM 中的旧位置,这很重要。