如何允许单个项目/子编辑器GWT-editor从包含它的ListEditor中删除它自己?例如点击移除按钮



在尝试使用GWT的ListEditor系统时,我找不到一个工作示例,其中列表中每个项目的UI都有一个删除/删除按钮。

我发现的示例都像这一个[1],并且有一个EditorSource.create()实现,它创建了每项Editor,并似乎连接了一个处理程序,通过listEditor.getList().remove(index)从底层列表中删除该项。

然而,删除处理程序的匿名实现在创建子编辑器时接近索引值,这会导致IndexOutOfBoundExceptions或错误的项被删除,因为每次删除都会更改其后所有项的索引。

我拔了一会儿头发,试图看看我在阻止这种情况发生的例子中遗漏了什么,但据我所知,他们确实都有这个问题,所以虽然解决方法相当简单,但我仍然会把它发布在这里,这样人们至少可以找到一个正确删除项目的例子。

[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; 
}
}

相关内容

最新更新