【发布时间】:2020-09-15 12:01:49
【问题描述】:
我正在制作仪表板创建工具。仪表板是一组行,每一行都有框。所以我试图列出项目列表。项目可以在列表之间移动。列表可以在彼此之间进行排序。 一切都保存在一个对象中,可以很容易地以 JSON 格式导出。很酷。
_________ ______________
| A B | move | A B C C |
|-------| C up |------------|
| C | ===> | |
|_______| |____________|
如果我将框 C 移动到第一行并调用重绘,则 C 框会复制自身。一个 C 是第二行的原始盒子,第二个 C 盒子是由模型中的秘银创建的。
关键是我只想在行之间移动框,而不是复制它。
我尝试使用 onbeforeupdate 和 m.redraw(),但这不是解决方案,因为我需要进行重绘循环。
class Grid {
private boxMap = new Map<TDashboardBox, IEditor>();
constructor(
public readonly dashboard: DashboardDAO,
private readonly editorFactory: IBoxFactory
) {
for (const row of dashboard.dashboard.config) {
for (const box of row) {
this.boxMap.set(box, editorFactory.create(box.title, box))
}
}
}
public boxView(box: TDashboardBox): Vnode {
return m(this.boxMap.get(box) || null);
}
public rowView(row: TDashboardRow): Vnode[] {
return row.map(b => m('.Box', {}, this.boxView(b)));
}
public view(): Vnode {
return m('.Grid', {},
this.dashboard.dashboard.config.map(r => m('.Row', {}, this.rowView(r)))
);
}
public oncreate(vnode: VnodeDOM): void {
Sortable.create(<HTMLElement>vnode.dom, {
group: "rows",
animation: 150,
onEnd: (e: SortableEvent) => {
this.dashboard.swapRows(e.oldIndex, e.newIndex);
},
});
const rows = vnode.dom.getElementsByClassName('Row');
for (let i = 0; i < rows.length; i++)
{
const row = <HTMLElement>rows[i];
Sortable.create(row, {
group: "boxes",
animation: 150,
onEnd: (e: SortableEvent) => {
const children = e.from.parentElement.childNodes;
// Search row indexes of "from row" and "to row"
let fromIndex, targetIndex;
for (let j = 0; j < children.length; j++) {
if (children[j] === e.from) {
fromIndex = j;
}
if (children[j] === e.to) {
targetIndex = j;
}
if (fromIndex !== undefined && targetIndex !== undefined) {
break;
}
}
this.dashboard.moveBox(fromIndex, e.oldDraggableIndex, targetIndex, e.newDraggableIndex);
m.redraw();
},
});
}
}
}
编辑 1
可以在 onEnd() 回调中删除复制的框。它解决了复制问题。
如果我在一行上交换盒子,它们会在模型中交换。但重绘后在屏幕上它们被交换回来。
编辑 2
我找到了一些解决方案。差不多了。
// End of onEnd() event
// if boxes moved, then...
m.render(vnode.dom, m(this)); // redraw Grid scratch
我只是扔掉了整个 Grid 的 html,让秘银重建它。
但现在在 Grid 中只是没有事件的 HTML,没有重绘周期。
【问题讨论】:
标签: typescript mithril.js sortablejs