GWT SelectionModel 正在返回旧选择

发布于 2024-12-07 02:53:03 字数 93 浏览 0 评论 0原文

我有一个带有异步数据提供程序的单元格表。如果我通过数据提供程序更新数据,表会正确呈现新数据,但选择模型仍然保留并返回旧对象。

有什么想法如何刷新选择模型吗?

I have a cell table with an async data provider. If I update the data via the data provider the table renders the new data correctly but the selection model still holds onto and returns old objects.

Any ideas how to refresh the selection model?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凤舞天涯 2024-12-14 02:53:03

我认为您应该使用适当的 ProvidesKey 让您的 SelectionModel 与同一“逻辑”对象的不同实例一起使用。例如,您可以使用 ProvidesKey 在对象上调用 getId,这样具有相同 ID 的两个对象将被视为相等;因此,即使 SelectionModel 保留对象,当您向它提供对象时,它仍然可以回答“是的,它已被选中”。
仅供参考,这正是 EntityProxyKeyProvider 所做的(使用代理的 stableId)。当您未指定时,默认使用的 SimpleKeyProvider 使用对象本身作为其键。

I think you should make your SelectionModel work with different instance of the same "logical" object using the appropriate ProvidesKey. For instance, you could use ProvidesKey that calls getId on the object, so that two objects with the same such ID would be considered equal; so even if the SelectionModel holds onto the old object, it can still answer "yes, it's selected" when you give it the new object.
FYI, this is exactly what the EntityProxyKeyProvider does (using the stableId of the proxy). And the SimpleKeyProvider, used by default when you don't specify one, uses the object itself as its key.

画离情绘悲伤 2024-12-14 02:53:03

我遇到了同样的问题。目前我将此作为单一选择模型。

SelectedRow = 当您选择它时存储它。

然后,当数据重新加载时,您可以通过

celltable.getSelectionModel().setSelected(SelectedRow, false);

清除它我想这对你来说已经太晚了,但希望它对其他人有帮助。

I came across the same issue. Currently I have this as single selection model.

SelectedRow = store it when you select it.

Then when data is reloaded you can clear it by

celltable.getSelectionModel().setSelected(SelectedRow, false);

I guess it is too late for you but hope it helps someone else.

荆棘i 2024-12-14 02:53:03

这是我刷新 SelectionModel 的手动方法。这允许您在需要时使用 selectedSet(),它实际上包含当前数据,而不是旧数据 - 包括删除已删除的行和更新的字段!

我已经包括了位和;扩展 DataGrid 的类的一部分。这至少应该具有解决您的问题的所有逻辑。

  1. 当选择一行时,调用saveSelectionKeys()。

  2. 当网格数据更改时,调用 refeshSelectedSet()。

  3. 如果您知道密钥类型,则可以用更容易处理的方法替换 isSameKey() 方法。此类使用泛型,因此此方法尝试找出对象转换本身。

public abstract class AsyncDataGrid<T> extends DataGrid<T> {
    ...

    private MultiSelectionModel<T> selectionModel_; 
    private ListDataProvider<T> dataProvider_;
    private List<T> dataList_;      
    private Set<Object> priorSelectionKeySet_;
    private boolean canCompareKeys_;
    ...

    public AsyncDataGrid( final ProvidesKey<T> keyProvider ){
        super( keyProvider );

        ...

        dataProvider_ = new ListDataProvider<T>();         
        dataList_ = dataProvider_.getList();            
        canCompareKeys_ = true;
        ...
    }   

    private void saveSelectionKeys(){
        priorSelectionKeySet_ = new HashSet<Object>();
        Set<T> selectedSet = selectionModel_.getSelectedSet();
        for( Iterator<T> it = selectedSet.iterator(); it.hasNext(); ) {
            priorSelectionKeySet_.add( super.getValueKey( it.next() ) );
        }
    }

    private void refeshSelectedSet(){
        selectionModel_.clear();
        if( priorSelectionKeySet_ != null ){
            if( !canCompareKeys_ ) return; 
            for( Iterator<Object> keyIt = priorSelectionKeySet_.iterator(); keyIt.hasNext(); ) {            
                Object priorKey = keyIt.next();         
                for( Iterator<T> it = dataList_.iterator(); it.hasNext(); ) {
                    T row = it.next();
                    Object rowKey = super.getValueKey( row );
                    if( isSameKey( rowKey, priorKey ) ) selectionModel_.setSelected( row, true );
                }
            }       
        }
    }

    private boolean isSameRowKey( final T row1, final T row2 ) {
        if( (row1 == null) || (row2 == null) ) return false;
        Object key1 = super.getValueKey( row1 );
        Object key2 = super.getValueKey( row2 );
        return isSameKey( key1, key2 );
    }   

    private boolean isSameKey( final Object key1, final Object key2 ){  
        if( (key1 == null) || (key1 == null) ) return false;        
        if(      key1 instanceof Integer ){
            return ( ((Integer) key1) - ((Integer) key2) == 0 );            
        }
        else if( key1 instanceof Long ){
            return ( ((Long) key1) - ((Long) key2) == 0 );          
        }
        else if( key1 instanceof String ){
            return ( ((String) key1).equals( ((String) key2) ) );           
        }       
        canCompareKeys_ = false;
        return false;
    }
}

Here is my manual method for refreshing the SelectionModel. This allows you to use the selectedSet() when needed and it will actually contain the current data, rather than the old data - including the removal of deleted rows and updated fields!

I have included bits & pieces of a class extending DataGrid. This should have all the logic at least to solve your problems.

  1. When a row is selected, call saveSelectionKeys().

  2. When the grid data is altered call refeshSelectedSet().

  3. If you know the key type, you can replace the isSameKey() method with something easier to deal with. This class uses generics, so this method attempts to figure out the object conversion itself.

.

public abstract class AsyncDataGrid<T> extends DataGrid<T> {
    ...

    private MultiSelectionModel<T> selectionModel_; 
    private ListDataProvider<T> dataProvider_;
    private List<T> dataList_;      
    private Set<Object> priorSelectionKeySet_;
    private boolean canCompareKeys_;
    ...

    public AsyncDataGrid( final ProvidesKey<T> keyProvider ){
        super( keyProvider );

        ...

        dataProvider_ = new ListDataProvider<T>();         
        dataList_ = dataProvider_.getList();            
        canCompareKeys_ = true;
        ...
    }   

    private void saveSelectionKeys(){
        priorSelectionKeySet_ = new HashSet<Object>();
        Set<T> selectedSet = selectionModel_.getSelectedSet();
        for( Iterator<T> it = selectedSet.iterator(); it.hasNext(); ) {
            priorSelectionKeySet_.add( super.getValueKey( it.next() ) );
        }
    }

    private void refeshSelectedSet(){
        selectionModel_.clear();
        if( priorSelectionKeySet_ != null ){
            if( !canCompareKeys_ ) return; 
            for( Iterator<Object> keyIt = priorSelectionKeySet_.iterator(); keyIt.hasNext(); ) {            
                Object priorKey = keyIt.next();         
                for( Iterator<T> it = dataList_.iterator(); it.hasNext(); ) {
                    T row = it.next();
                    Object rowKey = super.getValueKey( row );
                    if( isSameKey( rowKey, priorKey ) ) selectionModel_.setSelected( row, true );
                }
            }       
        }
    }

    private boolean isSameRowKey( final T row1, final T row2 ) {
        if( (row1 == null) || (row2 == null) ) return false;
        Object key1 = super.getValueKey( row1 );
        Object key2 = super.getValueKey( row2 );
        return isSameKey( key1, key2 );
    }   

    private boolean isSameKey( final Object key1, final Object key2 ){  
        if( (key1 == null) || (key1 == null) ) return false;        
        if(      key1 instanceof Integer ){
            return ( ((Integer) key1) - ((Integer) key2) == 0 );            
        }
        else if( key1 instanceof Long ){
            return ( ((Long) key1) - ((Long) key2) == 0 );          
        }
        else if( key1 instanceof String ){
            return ( ((String) key1).equals( ((String) key2) ) );           
        }       
        canCompareKeys_ = false;
        return false;
    }
}
甜味超标? 2024-12-14 02:53:03

我通过使用以下代码返回可见选择来解决我的特定问题。它使用选择模型来确定选择的内容,并将其与可见内容相结合。对象本身是从 CellTable 数据返回的,如果数据曾通过异步提供程序更改过,则该数据始终是最新的(选择模型数据可能已过时,但键将是正确的)

public Set<T> getVisibleSelection() {

    /*
     * 1) the selection model contains selection that can span multiple pages -
     * we want to return just the visible selection
     * 2) return the object from the cellTable and NOT the selection - the
     * selection may have old, stale, objects if the data has been updated
     * since the selection was made
     */
    Set<Object> selectedSet = getKeys(selectionModel.getSelectedSet());
    List<T> visibleSet = cellTable.getVisibleItems();
    Set<T> visibleSelectionSet = new HashSet<T>();
    for (T visible : visibleSet) {
        if (selectedSet.contains(KEY_PROVIDER.getKey(visible))) {
            visibleSelectionSet.add(visible);
        }
    }

    return visibleSelectionSet;
}

public static Set<Object> getKeys(Collection<T> objects) {

    Set<Object> ids = new HashSet<Object>();
    for (T object : objects) {
        ids.add(KEY_PROVIDER.getKey(object));
    }
    return ids;
}

I fixed my particular issue by using the following code to return the visible selection. It uses the selection model to determine what is selected and combines this with what is visible. The objects themselves are returned from the CellTable data which is always upto date if the data has ever been changed via an async provider (the selection model data maybe stale but the keys will be correct)

public Set<T> getVisibleSelection() {

    /*
     * 1) the selection model contains selection that can span multiple pages -
     * we want to return just the visible selection
     * 2) return the object from the cellTable and NOT the selection - the
     * selection may have old, stale, objects if the data has been updated
     * since the selection was made
     */
    Set<Object> selectedSet = getKeys(selectionModel.getSelectedSet());
    List<T> visibleSet = cellTable.getVisibleItems();
    Set<T> visibleSelectionSet = new HashSet<T>();
    for (T visible : visibleSet) {
        if (selectedSet.contains(KEY_PROVIDER.getKey(visible))) {
            visibleSelectionSet.add(visible);
        }
    }

    return visibleSelectionSet;
}

public static Set<Object> getKeys(Collection<T> objects) {

    Set<Object> ids = new HashSet<Object>();
    for (T object : objects) {
        ids.add(KEY_PROVIDER.getKey(object));
    }
    return ids;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文