#gwt #smartgwt
#gwt #smartgwt
Вопрос:
Представьте, что поле источника данных зависит от значений другого источника данных. Каким образом каждая 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, который можно найти здесь .
Ответ №1:
После некоторых поисков и экспериментов я обнаружил, что вы не можете так легко уведомить каждого пользователя об источнике данных. Источник данных вызывает fireCallback
каждого отдельного слушателя, когда processResponse
он был вызван. Увы, я не смог воссоздать функциональность, но, к счастью, я нашел обходной путь для этой ситуации:
Вам необходимо вручную аннулировать кеш каждого слушателя. Для ListGrid это можно сделать с invalidateCache
помощью and, но 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
, но это более эффективно.