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

Posted

技术标签:

【中文标题】ng2-dragula 添加新项目后显示在顶部【英文标题】:ng2-dragula after adding new item it's getting displayed at the top 【发布时间】: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 进行复制 如果不能复现就很难帮你了。 【参考方案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 中的旧位置,这很重要。

【讨论】:

感谢分享解决方案。这对我帮助很大。我看到列表末尾添加了项目。

以上是关于ng2-dragula 添加新项目后显示在顶部的主要内容,如果未能解决你的问题,请参考以下文章

在顶部添加新项目后,回收器视图未滚动到顶部,因为尚未发生对列表适配器的更改

在顶部添加新项目时在 ListView 中保持滚动位置

为什么我的Recyclerview在随机位置添加新项目?

如何在 Odoo 14 的***菜单下添加新项目?

需要使用 Firebase 在表格视图控制器 Xcode 7 中安排显示模式

SSIS 项目不会显示添加的新文件夹