【问题标题】:ng2-dragula after adding new item it's getting displayed at the topng2-dragula 添加新项目后显示在顶部
【发布时间】:2020-12-11 09:10:17
【问题描述】:

我正在使用 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>

我从评论中编辑了 stackblitz 以帮助可视化问题。这似乎是在将一个单位拖到列表底部时触发的。更新堆栈闪电战:https://stackblitz.com/edit/ng2-dragula-base-ykm8fz?file=src/app/app.component.html ItemsAddedOutOfOrder

【问题讨论】:

  • 而不是做 items.push()。尝试做 items.unshift()。
  • @Muhammad Kamran - 尝试使用 unshift,结果相同。事实上,随着这个变化,项目总是被添加到顶部。只有当我们将任何元素拖到末尾时才会添加它之前
  • 你能在这里复制吗? stackblitz.com/edit/…
  • @yurzui - 我无法在共享的 stackblitz url 中重现。但是在本地我可以用 angular 9 进行复制
  • 如果不能复现就很难帮你了。

标签: javascript angular angular9 dragula ng2-dragula


【解决方案1】:

您可以尝试在放置时恢复旧项目的位置。

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 总是返回 ViewContainer host(Comment node)ref

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 返回最后渲染的节点(最后一个&lt;li/&gt; 元素)ref

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

解决方案可能是将拖动的元素恢复为原始容器,以便我们可以让内置的 ngForOf Angular 指令进行智能差异。

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

【讨论】:

  • 感谢分享解决方案。这对我帮助很大。我看到列表末尾添加了项目。
猜你喜欢
  • 2012-08-26
  • 1970-01-01
  • 2021-04-27
  • 2019-01-26
  • 1970-01-01
  • 2022-07-26
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
相关资源
最近更新 更多