ListDataProvider.getList()。remove不使用KeyProvider

时间:2015-01-28 15:14:06

标签: gwt celltable gwt-celltable

调用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());

1 个答案:

答案 0 :(得分:1)

不,这不是错误,也不是它不使用您提供的getKey实现来查找该列表中的元素,因为该方法用于其他操作。忍受我......

ListDataProvider使用实现ListWrapper接口的ListListWrapper由保存对象的普通List支持。 ListWrapper具有您正在使用的方法(添加,设置,删除等)的实现,这些方法操纵您传递的List Lists.newArrayList(ri1, ri2)

这种操作是通过调用List接口的标准操作来完成的。所以被调用以确定应该删除哪个对象的是indexOf,这就是说ArrayList(这就是你要传递的东西,所以正在使用的东西)使用(如你所料){ {1}} equals的方法,如果您没有覆盖,则可以在TestVO类中找到。

您提供的Object方法用于标识行列表中的行(在您正在使用的显示内部,如getKey)。这可以在DataGrid中找到。调用方法的方法由其他方法调用(请参阅我在那里做的:P),以便识别需要执行某些操作的行。一个例子是更新AbstractDataProvider内的行。确定更新哪一行的方法是您提供的方法。因此,如果您的实现没有提供唯一键,您将指示具有相同键的所有行的更新。所以要小心。

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

这是GWT的实施

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