Ich habe eine GWT Cell Tree, die ich verwenden, um eine Dateistruktur von einem CMS anzuzeigen. Ich verwende eine , die Daten aus einer benutzerdefinierten RPC-Klasse, die ich erstellt habe, lädt. Ich habe auch ein Web Socket-System, das Ereignisse (Datei erstellen, umbenennen, verschieben, löschen usw.) von anderen Clients, die ebenfalls im System arbeiten, überträgt.Wie kann ich einem GWT-Zellen-Widget mitteilen, dass sich Daten über den Event-Bus geändert haben?
Was ich versuche, meinen Kopf zu wickeln ist, wenn ich eines dieser Ereignisse erhalte, wie ich meinen Zellenbaum richtig aktualisiere?
Ich nehme an, dieses Problem wäre analog zu zwei Instanzen meiner Cell Tree auf der Seite, die die gleichen serverseitigen Daten präsentieren und sicherstellen möchten, dass, wenn der Benutzer aktualisiert, dass der andere auch aktualisiert wird, über die EventBus
.
Ich denke, das sollte ziemlich einfach sein, aber ich habe jetzt etwa 6 Stunden darauf ohne Fortschritt verbracht. Mein Code ist unten enthalten:
HINWEIS: Ich verwende keine RequestFactory, obwohl es aussehen mag, als ob ich es ist mein eigenes RPC-Framework. Außerdem ist FileEntity nur eine einfache Darstellung einer Datei mit einem Namen, auf den durch getName()
zugegriffen werden kann.
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());
}
}
}
Nicht genau das, was ich gesucht habe, aber das funktioniert. Was halten Sie davon, einen Index FileEntity-> TreeNode zu pflegen, um die Suchzeiten zu verbessern? Vielen Dank! –
Ja ist es immer eine bessere Indizierung zu verwenden ... – Adarsha