使用Dijit.Tree和QueryReadStore进行延迟加载

时间:2011-06-18 02:26:01

标签: lazy-loading dojo

我正在尝试使用dojox.data.QueryReadStore作为延迟加载dijit.tree的商店。我似乎很难找到使用这个商店而不是JsonRestStore的人的例子,但为了整个应用程序的一致性,我真的很想坚持使用查询字符串而不是REST语法。麻烦的是,虽然我可以让QueryReadStore传递树的根级别,但延迟加载子节点,它总是失败。

这就是我所拥有的:

        dojo.require("dojox.data.QueryReadStore");
        dojo.require("dijit.Tree");



        dojo.addOnLoad(function() {
            var store = new dojox.data.QueryReadStore({
                url:'/cgi-bin/safari/safari_json_responder.pl',
                requestMethod: "get"
            });

            var treeModel = new dijit.tree.ForestStoreModel({
                store: store,
                deferItemLoadingUntilExpand: true,
                query: { 'id' : "0" },
                childrenAttrs: ["children"]
            });

            var myTree = new dijit.Tree({
                model: treeModel
            },
            "treeOne");

            myTree.startup();

        });

当我点击展开其中一个有孩子的类别时,我从Firebug中收到此错误:

  

无法在层次结构“code:”3中的指定点插入节点   [Break On此错误](function(){var _1 = null; if((_ 1 ||(typeo ... setTimeout(dojo._loadInit,100);}}})();

有关可能出现问题的任何建议?您可以在此处查看实时测试页面:

http://asisaid.com/safari-resources/lazyLoad.html

更新的观察结果19-Jun-2011:

我注意到isItemLoaded似乎声称在QueryReadStore中不完整。也许Dojo文档说QueryReadStore可以处理延迟加载是不正确的?我一直在尝试替换QueryReadStore.isItemLoaded方法,但还无法弄清楚它应该做什么。我试着寻找属性“$ ref”或“_reference”,但这似乎并没有起作用。

显然,我做错了什么。虽然不知怎的,我觉得我走在正确的轨道上。如果我可以通知模型一个项目没有完全加载,那么事情可能就会发生(他们应该采取行动)(和JsonRestStore一样)。

当id = 0传递给服务器时,以下是输出数据的样子:

{"label":"name","identification":"id","items":[{"name":"Autobiographical","poid":"0","id":"3"},{"name":"Blogging","poid":"0","children":[{"name":"asisaid","id":"2","$ref":"2"},{"name":"blogware","id":"4","$ref":"4"}],"id":"1","$ref":"1"}, [...]

(被截断以防止它太长。)

我在这里和那里抛出了引用和数据尝试不同的东西(我确信在这个例子中我有太多东西,但我一直试图抛出一切,看看有什么东西)。

最初看起来像id = 0:

{"label":"name","identification":"id","items":[{"name":"Autobiographical","poid":"0","id":"3"},{"name":"Blogging","poid":"0","children": "true","id":"1","$ref":"1"}, [...]

我也试过这个:

{"label":"name","identification":"id","items":[{"name":"Autobiographical","poid":"0","id":"3"},{"name":"Blogging","poid":"0","children": [{"$ref":"2" },{"$ref":"4"}],"id":"1"}, [...]

这些想法都没有(也不一样,但使用“_reference”代替“$ ref”似乎可以解决这个问题。

1 个答案:

答案 0 :(得分:1)

编辑:忘掉references。您仍然遇到children属性描述的问题,但是从查看QueryReadStoreTreeStoreModel的源代码我看不出它是如何工作的,至少在版本1.6中。另请参阅http://bugs.dojotoolkit.org/ticket/5876。它表示你不需要引用,你可以直接传递id值。但同样,我不确定它是否会奏效。您可能需要从QueryReadStore继承并覆盖某些方法。


您的服务器脚本返回children属性的无效值。当它返回其他项的引用列表或项本身时,它返回true。因为在您的情况下,您希望延迟加载子项直到扩展,children属性应该有引用。请参阅Dojo参考指南中的this页面。

类似的东西:

{
  "label":"name",
  "identification":"id",
  "items":[
    {
      "id":3,
      "name":"Autobiographical"
    },
    {
      "id":1,
      "name":"Blogging",
      "children": [
        {_reference:100}, {_reference:101}
      ]
    },
    ...
  ]
}

其中id 100101并不一定在第一批数据中返回,但可以稍后通过对您的服务器执行新查询来提取。

此外,ForestTreeModel中的查询应该是返回 root 项的内容。 {id:0}不是这样的条件。您可以为所有返回的项添加虚拟属性root,并将其设置为true以获取根。虽然{id:0}现在似乎可以正常工作,但是当树需要重新查询根项并且商店使用已经加载的数据时,它可能会引发您的兴趣。