6

CMS からファイル構造を表示するために使用する GWT セル ツリーがあります。AsyncDataProvider作成したカスタム RPC クラスからデータをロードするを使用しています。また、システムで動作している他のクライアントからイベント (ファイルの作成、名前変更、移動、削除など) をブロードキャストする Web ソケット システムもあります。

私が頭を包み込もうとしているのは、これらのイベントのいずれかを受け取ったときに、セルツリーを正しく更新する方法です。

この問題は、同じサーバー側のデータを提示し、ユーザーが一方を更新したときに、EventBus.

これはかなり単純なはずだと思いますが、今のところ約 6 時間費やしていますが、何も進んでいません。私のコードは以下に含まれています:

注: RequestFactory は、カスタム RPC フレームワークのように見えるかもしれませんが、使用していません。また、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());
            }
        }
    }
4

2 に答える 2

2

現在、最新のgwtバージョンでも、個々のツリーアイテムの更新は直接サポートされていません。

ただし、これには回避策があります。各ツリーアイテムは値に関連付けられています。この値を使用すると、対応するツリーアイテムを取得できます。

あなたの場合、どのアイテムを更新/更新するか、つまりどのファイルエンティティが変更されたかを知っていると思います。このファイルエンティティを使用して、対応するツリーアイテムを検索します。ツリーアイテムを取得したら、その親アイテムを展開して折りたたむか、折りたたんで展開する必要があります。これにより、親アイテムが子を再レンダリングします。変更されたファイルエンティティは、子の1つです。だからそれはリフレッシュされます。

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); 
       }
}
于 2013-02-27T15:16:11.927 に答える
0

データプロバイダーを使用してセルツリーを更新できます。完全なセル ツリーを次のように更新できます。

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

特別なセルだけを更新したい場合は、dataprovider から listwrapper を取得して、1 つの要素のみを設定できます。

provider.getList().set(12, element);
于 2013-02-26T08:42:12.510 に答える