如何允许 single-item/sub-editor GWT 编辑器从包含它的 ListEditor 中删除自身?例如单击删除按钮
How do I allow a single-item/sub-editor GWT Editor to remove itself from a ListEditor that contains it? e.g. on remove button clicked
在尝试使用 GWT 的 ListEditor
系统时,我无法找到一个工作示例,其中列表中每个项目的 UI 都有一个 delete/remove 按钮。
我找到的例子都像 this one[1] 并且有一个 EditorSource.create()
实现创建每个项目 Editor
并且似乎连接一个处理程序来删除项目来自基础列表 listEditor.getList().remove(index)
。
但是,删除处理程序的匿名实现在子编辑器创建时围绕索引值关闭,这导致 IndexOutOfBoundExceptions
或错误的项目被删除,因为每次删除都会更改索引在它之后的所有项目中。
我绞尽脑汁想看看我在示例中遗漏了什么,以防止这种情况发生,但据我所知,他们确实都遇到了这个问题,所以虽然修复相当简单,我仍将 post 放在这里,这样人们至少可以找到一个正确删除项目的示例。
[1] 我认为我找到的所有示例都来自我链接的那个,尽管那个特别是在 remove() 中有更多的逻辑,并且可能一直在做一些事情来避免这个问题,比如更正列表顺序不知何故,我还没有深入研究该项目中的其他代码。
以下是一个最小的 ListEditor
示例,它更正了在其他示例中发现的问题。
public abstract class FooEditor extends Composite implements Editor<Foo> {
Widget root; // Instantiated explicitly or through uibinder
// Implemented as one of uibinder+fields, fields, methods, or LeafValueEditor.set/getValue()
public FooEditor() {
initWidget(root);
}
// Used for brevity, could be any triggering mechanism, click handler, event handler, etc.
abstract void onDeleteClicked();
}
public class FooListEditor extends Composite implements IsEditor<ListEditor<Foo, FooEditor>> {
private class FooEditorSource extends EditorSource<FooEditor> {
@Override
public FooEditor create(int index) {
FooEditor subEditor = new FooEditor()
{
@Override
public void onDeleteClicked()
{
// =======================================================
//
// This fixes the problem present in other examples
// by determining the current index at the time of removal
//
// =======================================================
int currentIndex = listEditor.getEditors().indexOf(this);
listEditor.getList().remove(currentIndex);
}
};
setIndex(subEditor, index);
return subEditor;
}
@Override
public void dispose(FooEditor subEditor) {
subEditor.removeFromParent();
}
@Override
public void setIndex(FooEditor subEditor, int index) {
listPanel.insert(subEditor, index);
}
}
FlowPanel listPanel; // Instantiated explicitly or through uibinder
ListEditor<Foo, FooEditor> listEditor = ListEditor.of(new FooEditorSource());
public FooListEditor() {
initWidget(listPanel);
}
@Override
public ListEditor<Foo, FooEditor> asEditor() {
return listEditor;
}
}
在尝试使用 GWT 的 ListEditor
系统时,我无法找到一个工作示例,其中列表中每个项目的 UI 都有一个 delete/remove 按钮。
我找到的例子都像 this one[1] 并且有一个 EditorSource.create()
实现创建每个项目 Editor
并且似乎连接一个处理程序来删除项目来自基础列表 listEditor.getList().remove(index)
。
但是,删除处理程序的匿名实现在子编辑器创建时围绕索引值关闭,这导致 IndexOutOfBoundExceptions
或错误的项目被删除,因为每次删除都会更改索引在它之后的所有项目中。
我绞尽脑汁想看看我在示例中遗漏了什么,以防止这种情况发生,但据我所知,他们确实都遇到了这个问题,所以虽然修复相当简单,我仍将 post 放在这里,这样人们至少可以找到一个正确删除项目的示例。
[1] 我认为我找到的所有示例都来自我链接的那个,尽管那个特别是在 remove() 中有更多的逻辑,并且可能一直在做一些事情来避免这个问题,比如更正列表顺序不知何故,我还没有深入研究该项目中的其他代码。
以下是一个最小的 ListEditor
示例,它更正了在其他示例中发现的问题。
public abstract class FooEditor extends Composite implements Editor<Foo> {
Widget root; // Instantiated explicitly or through uibinder
// Implemented as one of uibinder+fields, fields, methods, or LeafValueEditor.set/getValue()
public FooEditor() {
initWidget(root);
}
// Used for brevity, could be any triggering mechanism, click handler, event handler, etc.
abstract void onDeleteClicked();
}
public class FooListEditor extends Composite implements IsEditor<ListEditor<Foo, FooEditor>> {
private class FooEditorSource extends EditorSource<FooEditor> {
@Override
public FooEditor create(int index) {
FooEditor subEditor = new FooEditor()
{
@Override
public void onDeleteClicked()
{
// =======================================================
//
// This fixes the problem present in other examples
// by determining the current index at the time of removal
//
// =======================================================
int currentIndex = listEditor.getEditors().indexOf(this);
listEditor.getList().remove(currentIndex);
}
};
setIndex(subEditor, index);
return subEditor;
}
@Override
public void dispose(FooEditor subEditor) {
subEditor.removeFromParent();
}
@Override
public void setIndex(FooEditor subEditor, int index) {
listPanel.insert(subEditor, index);
}
}
FlowPanel listPanel; // Instantiated explicitly or through uibinder
ListEditor<Foo, FooEditor> listEditor = ListEditor.of(new FooEditorSource());
public FooListEditor() {
initWidget(listPanel);
}
@Override
public ListEditor<Foo, FooEditor> asEditor() {
return listEditor;
}
}