Ho una cella GWT che utilizzo per visualizzare una struttura di file da un CMS. Sto usando un AsyncDataProvider
che carica i dati da una classe RPC personalizzata che ho creato. Ho anche un sistema Web Socket che trasmetterà eventi (File create, rinominato, spostato, cancellato, ecc.) Da altri client che funzionano anche nel sistema.Come si comunica a un GWT che i dati del widget della cella sono stati modificati tramite il bus eventi?
Quello che sto cercando di comprendere è quando ricevo uno di questi eventi, come aggiorno correttamente il mio albero cellulare?
Suppongo che questo problema sia analogo a due istanze del mio albero cellulare nella pagina, che presentano gli stessi dati lato server e che vogliono garantire che quando l'utente ne ha aggiornato uno, che anche l'altro sia aggiornato, via usando il EventBus
.
Ritengo che questo dovrebbe essere piuttosto semplice, ma ho trascorso circa 6 ore su di esso ora senza alcun progresso. Il mio codice è incluso di seguito:
NOTA: Non sto utilizzando RequestFactory anche se potrebbe sembrare come se fosse il mio framework RPC personalizzato. Inoltre, FileEntity è solo una semplice rappresentazione di un file che ha un nome accessibile da getName()
.
private void drawTree() {
// fileService is injected earlier on and is my own custom rpc service
TreeViewModel model = new CustomTreeModel(new FileDataProvider(fileService));
CellTree tree = new CellTree(model, "Root");
tree.setAnimationEnabled(true);
getView().getWorkspace().add(tree);
}
private static class CustomTreeModel implements TreeViewModel {
// I am trying to use a single AsyncDataProvider so I have a single point of loading data which I can manipulate (Not sure if this is the correct way to go)
public CustomTreeModel(FileDataProvider dataProvider) {
this.provider = provider;
}
public <T> NodeInfo<?> getNodeInfo(final T value) {
if (!(value instanceof FileEntity)) {
// I already have the root File loaded in my presenter, if we are at the root of the tree, I just add it via a list here
ListDataProvider<FileEntity> dataProvider = new ListDataProvider<FileEntity>();
dataProvider.getList().add(TreeWorkspacePresenter.rootFolder);
return new DefaultNodeInfo<FileEntity>(dataProvider,
new FileCell());
} else {
// Otherwise I know that we are loading some tree child data, and I invoke the AsyncProvider to load it from the server
provider.setFocusFile(value);
return new DefaultNodeInfo<FileEntity>(provider,
new FileCell());
}
}
public boolean isLeaf(Object value) {
if(value == null || value instanceof Folder)
return false;
return true;
}
}
public class FileDataProvider extends AsyncDataProvider<FileEntity> {
private FileEntity focusFile;
private FileService service;
@Inject
public FileDataProvider(FileService service){
this.service = service;
}
public void setFocusFile(FileEntity focusFile){
this.focusFile = focusFile;
}
@Override
protected void onRangeChanged(HasData<FileEntity> display) {
service.getChildren(((Folder) focusFile),
new Reciever<List<FileEntity>>() {
@Override
public void onSuccess(List<FileEntity> files) {
updateRowData(0, files);
}
@Override
public void onFailure(Throwable error) {
Window.alert(error.toString());
}
});
}
}
/**
* The cell used to render Files.
*/
public static class FileCell extends AbstractCell<FileEntity> {
private FileEntity file;
public FileEntity getFile() {
return file;
}
@Override
public void render(Context context, FileEntity file, SafeHtmlBuilder sb) {
if (file != null) {
this.file = file;
sb.appendEscaped(file.getName());
}
}
}
Non esattamente quello che stavo cercando, ma questo funziona. Cosa ne pensi di mantenere un indice FileEntity-> TreeNode per migliorare i tempi di ricerca? Grazie! –
Sì, è sempre meglio usare l'indicizzazione ... – Adarsha