ListDataProvider.getList().remove 不使用 KeyProvider
ListDataProvider.getList().remove doesn't use the KeyProvider
调用 ListDataProvider.getList().remove(...) 不使用构造函数中传递的 KeyProvider。这是一个 GWT 错误还是它应该像这样工作?
我在下面附上了相关的单元测试。
谢谢,
TestVO ri1 = new TestVO();
ri1.setId(null);
ri1.setName("msg1");
TestVO ri2 = new TestVO();
ri2.setId(null);
ri2.setName("msg2");
TestVO ri3 = new TestVO();
ri3.setId(null);
ri3.setName("msg2");
ListDataProvider<TestVO> ldp = new ListDataProvider<>(new ProvidesKey<TestVO>() {
@Override
public Object getKey(TestVO pItem) {
System.out.println("this never gets invoked");
return pItem.getMessageType();
}
});
ldp.setList(Lists.newArrayList(ri1, ri2));
ldp.getList().remove(ri3);
//this currently fails, actual size is 1 as it removes ri2
assertEquals(2, ldp.getList().size());
不,这不是错误,也不,它不使用您提供的 getKey
实现来查找该列表中的元素,因为该方法用于其他操作。忍耐一下...
ListDataProvider
使用实现 List
接口的 ListWrapper
,ListWrapper
由保存对象的普通 List
支持。 ListWrapper
具有您正在使用的方法(添加、设置、删除等)的实现,这些方法操纵您传递给 Lists.newArrayList(ri1, ri2)
的 List
。
此操作是通过调用 List
接口的标准操作等方式完成的。因此,被调用以确定应删除哪个对象的是 indexOf
,让我们说 ArrayList
(这就是您要传递的内容,所以这就是正在使用的内容)使用(正如您所期望的那样) equals
TestVO
的方法,如果你没有覆盖,你可以在 Object
class.
中找到
您提供的 getKey
方法用于识别行列表中的行(在您使用的显示中,如 DataGrid
)。这可以在 AbstractDataProvider
中找到。这个调用你的方法的方法被其他方法调用(看看我在那里做了什么:P),以便识别需要一些操作的行。例如更新 DataGrid
中的一行。确定更新哪一行的方法是您提供的方法。因此,如果您的实现不提供唯一键,您将看到使用相同键对所有行进行更新的指示。所以要小心。
/**
* Get the key for a list item. The default implementation returns the item
* itself.
*
* @param item the list item
* @return the key that represents the item
*/
public Object getKey(T item) {
return keyProvider == null ? item : keyProvider.getKey(item);
}
indexOf
在ArrayList
中的实现
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
这是GWT的实现
/**
* Construct a new {@link ListWrapper} that delegates flush calls to the
* specified delegate.
*
* @param list the list to wrap
* @param delegate the delegate
* @param offset the offset of this list
*/
private ListWrapper(List<T> list, ListWrapper delegate, int offset) {
this.list = list;
this.delegate = delegate;
this.offset = offset;
}
@Override
public void add(int index, T element) {
try {
list.add(index, element);
minModified = Math.min(minModified, index);
maxModified = size();
modified = true;
flush();
} catch (IndexOutOfBoundsException e) {
throw new IndexOutOfBoundsException(e.getMessage());
}
}
@Override
public T remove(int index) {
try {
T toRet = list.remove(index);
minModified = Math.min(minModified, index);
maxModified = size();
modified = true;
flush();
return toRet;
} catch (IndexOutOfBoundsException e) {
throw new IndexOutOfBoundsException(e.getMessage());
}
}
@Override
public boolean remove(Object o) {
int index = indexOf(o);
if (index == -1) {
return false;
}
remove(index);
return true;
}
public void setList(List<T> listToWrap) {
listWrapper = new ListWrapper(listToWrap);
listWrapper.minModified = 0;
listWrapper.maxModified = listWrapper.size();
listWrapper.modified = true;
flush();
}
public List<T> getList() {
return listWrapper;
}
调用 ListDataProvider.getList().remove(...) 不使用构造函数中传递的 KeyProvider。这是一个 GWT 错误还是它应该像这样工作? 我在下面附上了相关的单元测试。
谢谢,
TestVO ri1 = new TestVO();
ri1.setId(null);
ri1.setName("msg1");
TestVO ri2 = new TestVO();
ri2.setId(null);
ri2.setName("msg2");
TestVO ri3 = new TestVO();
ri3.setId(null);
ri3.setName("msg2");
ListDataProvider<TestVO> ldp = new ListDataProvider<>(new ProvidesKey<TestVO>() {
@Override
public Object getKey(TestVO pItem) {
System.out.println("this never gets invoked");
return pItem.getMessageType();
}
});
ldp.setList(Lists.newArrayList(ri1, ri2));
ldp.getList().remove(ri3);
//this currently fails, actual size is 1 as it removes ri2
assertEquals(2, ldp.getList().size());
不,这不是错误,也不,它不使用您提供的 getKey
实现来查找该列表中的元素,因为该方法用于其他操作。忍耐一下...
ListDataProvider
使用实现 List
接口的 ListWrapper
,ListWrapper
由保存对象的普通 List
支持。 ListWrapper
具有您正在使用的方法(添加、设置、删除等)的实现,这些方法操纵您传递给 Lists.newArrayList(ri1, ri2)
的 List
。
此操作是通过调用 List
接口的标准操作等方式完成的。因此,被调用以确定应删除哪个对象的是 indexOf
,让我们说 ArrayList
(这就是您要传递的内容,所以这就是正在使用的内容)使用(正如您所期望的那样) equals
TestVO
的方法,如果你没有覆盖,你可以在 Object
class.
您提供的 getKey
方法用于识别行列表中的行(在您使用的显示中,如 DataGrid
)。这可以在 AbstractDataProvider
中找到。这个调用你的方法的方法被其他方法调用(看看我在那里做了什么:P),以便识别需要一些操作的行。例如更新 DataGrid
中的一行。确定更新哪一行的方法是您提供的方法。因此,如果您的实现不提供唯一键,您将看到使用相同键对所有行进行更新的指示。所以要小心。
/**
* Get the key for a list item. The default implementation returns the item
* itself.
*
* @param item the list item
* @return the key that represents the item
*/
public Object getKey(T item) {
return keyProvider == null ? item : keyProvider.getKey(item);
}
indexOf
在ArrayList
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
这是GWT的实现
/**
* Construct a new {@link ListWrapper} that delegates flush calls to the
* specified delegate.
*
* @param list the list to wrap
* @param delegate the delegate
* @param offset the offset of this list
*/
private ListWrapper(List<T> list, ListWrapper delegate, int offset) {
this.list = list;
this.delegate = delegate;
this.offset = offset;
}
@Override
public void add(int index, T element) {
try {
list.add(index, element);
minModified = Math.min(minModified, index);
maxModified = size();
modified = true;
flush();
} catch (IndexOutOfBoundsException e) {
throw new IndexOutOfBoundsException(e.getMessage());
}
}
@Override
public T remove(int index) {
try {
T toRet = list.remove(index);
minModified = Math.min(minModified, index);
maxModified = size();
modified = true;
flush();
return toRet;
} catch (IndexOutOfBoundsException e) {
throw new IndexOutOfBoundsException(e.getMessage());
}
}
@Override
public boolean remove(Object o) {
int index = indexOf(o);
if (index == -1) {
return false;
}
remove(index);
return true;
}
public void setList(List<T> listToWrap) {
listWrapper = new ListWrapper(listToWrap);
listWrapper.minModified = 0;
listWrapper.maxModified = listWrapper.size();
listWrapper.modified = true;
flush();
}
public List<T> getList() {
return listWrapper;
}