服务函数返回空对象

时间:2014-02-22 23:57:54

标签: javascript angularjs global-variables

我有一个工厂函数,它不会返回我想在控制器中设置的变量。我没有得到错误,只是变量不会被设置为它所设想的。

spApp.factory('SiteService', function ($q){
    var rootUrl = window.location.protocol + "//" + window.location.hostname;
    var siteMap;

    //returns object containing info about all sites within collection
    var getSiteMap = function () {
        siteMap = {};

        var promise = $().SPServices({
            operation: "GetAllSubWebCollection",
            async: true
        });

        promise.then(
            function (response){
                map = {}; //init the map
                var web = $(response).find("Web").map(function () {
                    return $(this).attr('Url');
                });
                var webTitle = $(response).find("Web").map(function () {
                    return $(this).attr('Title');
                });  

                // create map
                for (var i = 0; i < web.length; i++) {
                    var item = web[i],
                        title = webTitle[i],
                        parts = item.split('/'),
                        domain = parts.splice(0, 3).join('/'),
                        current;

                    if (!map[domain]) map[domain] = {url:domain, title:title ,children:{}};
                    current = map[domain].children;

                    for (var index in parts) {
                        var part = parts[index];
                        if (!current[part]) {
                            current[part] = {url:domain+'/'+parts.slice(0,index+1).join('/'), title:title, children:{}};
                        }
                        current = current[part].children;
                    }
                }
            siteMap = map;
        }, function(reason){
            alert('FAILED:' + reason);
        })
        console.log(siteMap);
        return siteMap;
    }

    return{
        getSiteMap:getSiteMap
    }
});

2 个答案:

答案 0 :(得分:0)

您遇到的问题是您正在使用承诺。当您将console.log放在then()函数之外时,您正在记录变量,然后才能实际解析。

如果您将console.log放在then()功能内(分配了站点地图后),它应显示正确的值,但您仍然无法可靠地访问它。

我认为在之后访问siteMap的最简单方法是填充数据,这是传入一个回调函数。例如:

var getSiteMap = function (_callback) {
    siteMap = {};

    $().SPServices({
        operation: "GetAllSubWebCollection",
        async: true
    }).then(function(response){
        // Process the data and set siteMap
        // ...
        siteMap = map;

        // now pass siteMap to the callback
        _callback(siteMap);
    });

然后您可以在控制器中使用它,如下所示:

SiteService.getSiteMap(function(sitemap){
    // Do something with your sitemap here
});

现在虽然这会起作用,但它只是一个简单的例子,并不一定是最好的方法。如果您不喜欢回调,则可以创建仅在分配siteMap时解析的第二个承诺。另外,根据getSiteMap()的使用情况,您可能希望缓存该值,否则每次都会调用该请求。

答案 1 :(得分:0)

尝试将这样的承诺链接起来:

var getSiteMap = function () {
    siteMap = {};

    var promise = $().SPServices({
        operation: "GetAllSubWebCollection",
        async: true
    });

     return promise.then(function(response){ //return your promise
        // all you code
        siteMap = map;

        return siteMap; //return a value to another .then in the chain
    });
 }

像这样使用:

SiteService.getSiteMap().then(function(siteMap){

});