2013-02-18 35 views
6

我有一個GWT單元格樹,我用它來顯示CMS的文件結構。我正在使用從我創建的自定義RPC類加載數據的AsyncDataProvider。我也有一個網絡套接字系統,可以從系統中的其他客戶端廣播事件(文件創建,重命名,移動,刪除等)。如何通過事件總線告訴GWT單元格小部件數據已更改?

我試圖包裹我的頭是當我收到這些事件之一,我如何正確更新我的細胞樹?

我想這個問題可能類似於我的單元格樹的兩個實例在頁面上,它們呈現相同的服務器端數據,並希望確保當用戶更新一個,另一個更新時,通過使用EventBus

我覺得這應該很簡單,但我現在已經花了大約6個小時,沒有進展。我的代碼包括如下:

注意:即使它看起來像我是我的自定義RPC框架,我沒有使用RequestFactory。此外,FileEntity只是一個文件的簡單表示,其名稱可由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()); 
      } 
     } 
    } 

回答

2

即使在最新的gwt版本中,當前也沒有對個別樹項目刷新的直接支持。

但是有一個解決方法。每個樹項都與一個值相關聯。使用此值可以獲取相應的樹項目。

在你的情況,我假設,你知道哪個項目更新/刷新,即你知道哪個文件實體已經改變。使用此文件實體搜索相應的樹項目。一旦獲得樹項目,您只需展開並摺疊或摺疊並展開其父項。這使父項重新呈現其子項。您更改的文件實體是其中的一個。所以它得到刷新。

public void refreshFileEntity(FileEntity fileEntity) 
{ 
     TreeNode fileEntityNode = getFileEntityNode(fileEntity, cellTree.getRootTreeNode() 

     // For expnad and collapse run this for loop 

     for (int i = 0; i < fileEntityNode.getParent().getChildCount(); i++) 
    { 
     if (!fileEntityNode.getParent().isChildLeaf(i)) 
     { 
      fileEntityNode.getParent().setChildOpen(i, true); 
     } 
    } 

} 

public TreeNode getFileEntityNode(FileEntity fileEntity, TreeNode treeNode) 
{ 
     if(treeNode.getChildren == null) 
     { 
      return null; 
     } 
     for(TreeNode node : treeNode.getChildren()) 
     { 
      if(fileEntity.getId().equals(node.getValue.getId())) 
      { 
       return node; 
      } 
      getEntityNode(fileEntity, node); 
     } 
} 
+0

不是我正在尋找的東西,但這是有效的。對於維護索引FileEntity-> TreeNode以改善查找時間,您有什麼想法?謝謝! – 2013-02-27 19:05:19

+0

是的,它總是更好地使用索引... – Adarsha 2013-02-28 03:13:40

0

您可以使用數據提供程序來更新celltree。 您可以用更新的完整細胞樹:

provider.setList(pList); 
provider.refresh(); 

如果您只想更新一個特殊的細胞,你可以從dataProvider中的listwrapper和只設置一個元素。

provider.getList().set(12, element); 
+0

這必須與AsyncDataProvider一起使用,其中新數據來自服務器。我不認爲這種方法會起作用... – 2013-02-26 16:17:06

相關問題