通过调用dojo模块返回对象存储值

时间:2014-06-23 18:24:24

标签: dojo

我希望得到一个值(一个对象存储)来调用我的dojo模块,但是我一直都未定义:

模块:

define(['dojo/store/Memory', 'dojo/_base/xhr', "dojo/data/ObjectStore"],
        function (Memory, xhr, ObjectStore) {
    var oReachStore;
    return {
        Reaches: function (url) {
            xhr.get({//get data from database
                url: url,
                //url: url,
                handleAs: "json",
                load: function (result) {
                    var ReachData = result.GetReachesResult; 
                    var ReachStore = new Memory({ data: ReachData, idProperty: "label" });
                    oReachStore = new ObjectStore({ objectStore: ReachStore });
                },
                error: function (err) { }

            });
        },
        GetReaches: function () {
            return oReachStore;
        }
    }

});

调用模块:

Data.Reaches(dataServiceUrl);//set the reach object store
ReachData = Data.GetReaches();//get the reach object store, but is always undefined

2 个答案:

答案 0 :(得分:1)

我需要为函数GetReach使用回调函数。以下修改后的代码有效: 模块:

define(['dojo/store/Memory', 'dojo/_base/xhr', "dojo/data/ObjectStore"],
function (Memory, xhr, ObjectStore) {
    return {
        GetReach: function (url, callback) {
            xhr.get({//get data from database
                url: url,
                //url: url,
                handleAs: "json",
                load: function (result) {
                    var ReachData = result.GetReachesResult; 
                    var ReachStore = new Memory({ data: ReachData, idProperty: "label" });
                    var oReachStore = new ObjectStore({ objectStore: ReachStore });
                    callback(oReachStore);
                },
                error: function (err) { }

            });
        }
    }
});

从主页致电:

// ....
Data.GetReach(dataServiceUrl, SetReach);
function SetReach(data) {
    //set data for the dropdown
    ddReach.setStore(data);
}

答案 1 :(得分:1)

就像你现在可能已经注意到的那样(通过阅读你的答案),你是否正在使用异步查找(在这种情况下XMLHttpRequest是异步的),但是你依赖于那个商店,在它之前可能会被设定。

可能的解决方案是使用promises / deferreds。我不知道你正在使用哪个Dojo版本,但是在Dojo< 1.8您可以使用dojo/_base/Deferred模块,从1.8开始,您可以使用dojo/Deferred模块。语法略有不同,但概念是相同的。

首先,您将oReachStore更改为:

var oReachStore = new Deferred();

然后,在Reaches功能中,您不能替换oReachStore,但使用Deferred::resolve()功能,例如:

return {
    Reaches: function (url) {
        xhr.get({//get data from database
            url: url,
            //url: url,
            handleAs: "json",
            load: function (result) {
                var ReachData = result.GetReachesResult; 
                var ReachStore = new Memory({ data: ReachData, idProperty: "label" });
                oReachStore.resolve(ew ObjectStore({ objectStore: ReachStore })); // Notice the difference
            },
            error: function (err) { }
        });
    },
    GetReaches: function () {
        return oReachStore;
    }
}

然后在你的代码中你可以使用:

Data.Reaches(dataServiceUrl);//set the reach object store
Data.GetReaches().then(function(ReachData) {
    console.log(ReachData); // No longer undefined
});

所以现在ReachData不会返回undefined,因为你等到它被解决了。

延迟实际上是JavaScript世界中的常见模式,与定义自己的回调相比,实际上是更加可靠的API。例如,如果您在XHR请求中收到错误,可以使用:

error: function(err) {
    oReachStore.reject(err);
}

一个简单的例子(我使用setTimeout()模拟了异步请求)可以在JSFiddle上找到:http://jsfiddle.net/86x9n/