监听DataSource操作并通知SmartGWT中的监听者
想象一下,一个数据源字段依赖于另一个数据源的值。每个使用该数据源的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过一番搜索和实验后,我发现您无法那么轻松地通知数据源的每个用户。当调用
processResponse
时,数据源会在每个单独的侦听器上调用fireCallback
。唉,我无法重新创建该功能,但幸运的是,我找到了解决这种情况的方法:您需要手动使每个侦听器的缓存无效。对于 ListGrid,可以使用
invalidateCache
来完成此操作,但对于 ComboBoxItem,可以使用invalidateDisplayValueCache
来完成此操作。例如:其他可能的解决方案可能是重新绘制整个
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, whenprocessResponse
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 withinvalidateDisplayValueCache
. E.g.:Other possible solutions could be to redraw the entire
ListGrid
, but this is more effecient.