监听DataSource操作并通知SmartGWT中的监听者

发布于 2024-12-12 12:41:00 字数 1816 浏览 1 评论 0原文

想象一下,一个数据源字段依赖于另一个数据源的值。每个使用该数据源的 ListGrid 如何自动收到任何更改通知? 如果可能,无需重绘整个ListGrid而只需重绘受影响的记录?

考虑以下类作为观察者

public class ObserverDataSource extends DataSource {

    public ObserverDataSource() {
    // This field needs to update/notify every ListGrid that uses 
    // this DataSource when a change occurs in the CountryDataSource.
        DataSourceField countryField = new DataSourceTextField("country", "Country");
        addField(countryField);
        // Other fields...
    }

    public void update() {
    // invalidateCache() doesn't work on its own.
    // What will make each object (ListGrid) that uses the DataSource refresh itself?
    // Even better if it only refreshes the changed records.
    // E.g. now a full redraw of the ListGrid.
    }

}

以及我们的可观察数据源:

public class ObservableDataSource extends DataSource {

    public ObservableDataSource() { 
    DataSourceField idField = new DataSourceIntegerField("id", "Id");
    idField.setPrimaryKey(true);       
    DataSourceField countryField = new DataSourceTextField("country", "Country");
    DataSourceField codeField = new DataSourceIntegerField("code", "Country code");
    setFields(idField, countryField, codeField);
    }

    public executeFetch(...) {
    // Doesn't change anything, don't notify observers.
    // Do logic...
    processResponse(requestId, response);
    }

    public executeAdd(...) {
    // Changed the data, notify the observer (MyDataSource instance).
    // Do logic...
    myDataSourceInstance.update();
    processResponse(requestId, response);
    }

}

注意:数据源模板基于GwtRpcDataSource,可以是在这里找到

Imagine that a DataSource field depends on the values of another DataSource. How would each ListGrid that uses that DataSource be automatically notified of any changes? If possible, without having to redraw the entire ListGrid but only the affected records?

Consider the following class as the observer:

public class ObserverDataSource extends DataSource {

    public ObserverDataSource() {
    // This field needs to update/notify every ListGrid that uses 
    // this DataSource when a change occurs in the CountryDataSource.
        DataSourceField countryField = new DataSourceTextField("country", "Country");
        addField(countryField);
        // Other fields...
    }

    public void update() {
    // invalidateCache() doesn't work on its own.
    // What will make each object (ListGrid) that uses the DataSource refresh itself?
    // Even better if it only refreshes the changed records.
    // E.g. now a full redraw of the ListGrid.
    }

}

And our observable DataSource:

public class ObservableDataSource extends DataSource {

    public ObservableDataSource() { 
    DataSourceField idField = new DataSourceIntegerField("id", "Id");
    idField.setPrimaryKey(true);       
    DataSourceField countryField = new DataSourceTextField("country", "Country");
    DataSourceField codeField = new DataSourceIntegerField("code", "Country code");
    setFields(idField, countryField, codeField);
    }

    public executeFetch(...) {
    // Doesn't change anything, don't notify observers.
    // Do logic...
    processResponse(requestId, response);
    }

    public executeAdd(...) {
    // Changed the data, notify the observer (MyDataSource instance).
    // Do logic...
    myDataSourceInstance.update();
    processResponse(requestId, response);
    }

}

Note: the DataSource template is based on GwtRpcDataSource, which can be found here.

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

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

发布评论

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

评论(1

月亮坠入山谷 2024-12-19 12:41:00

经过一番搜索和实验后,我发现您无法那么轻松地通知数据源的每个用户。当调用 processResponse 时,数据源会在每个单独的侦听器上调用 fireCallback。唉,我无法重新创建该功能,但幸运的是,我找到了解决这种情况的方法:

您需要手动使每个侦听器的缓存无效。对于 ListGrid,可以使用 invalidateCache 来完成此操作,但对于 ComboBoxItem,可以使用 invalidateDisplayValueCache 来完成此操作。例如:

public class ObserverDataSource extends DataSource {

    private Set<MyChangeHandler> handlers = new HashSet<MyChangeHandler>();

    public void update() {
        for(MyChangeHandler handler : handlers){
            handler.onChanged(/* Calls invalidateCache on itself */);
        }
    }

}

其他可能的解决方案可能是重新绘制整个 ListGrid,但这更有效。

After some searching, and experimenting, I found out that you can't notify every user of the DataSource that easily. A datasource calls fireCallback on each separate listener, when processResponse has been called. Alas, I couldn't recreate the functionality, but luckily I found a workaround for the situation:

You need to invalidate the cache of each listener manually. For ListGrid this can be done with invalidateCache and but ComboBoxItem with invalidateDisplayValueCache. E.g.:

public class ObserverDataSource extends DataSource {

    private Set<MyChangeHandler> handlers = new HashSet<MyChangeHandler>();

    public void update() {
        for(MyChangeHandler handler : handlers){
            handler.onChanged(/* Calls invalidateCache on itself */);
        }
    }

}

Other possible solutions could be to redraw the entire ListGrid, but this is more effecient.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文