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 返回最后渲染的节点(最后一个<li/>
元素)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 添加新项目后显示在顶部的主要内容,如果未能解决你的问题,请参考以下文章
在顶部添加新项目后,回收器视图未滚动到顶部,因为尚未发生对列表适配器的更改