简体   繁体   English

服务函数返回空对象

[英]Service function returning empty object

I've got a factory function that won't return a variable I'm trying to set in my controller. 我有一个工厂函数,该函数不会返回我要在控制器中设置的变量。 I don't get an error though, just the variable won't get set to what it's suppose to. 不过,我没有收到错误,只是变量不会设置为假定的值。

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
    }
});

The issue you have is that you are working with promises. 您遇到的问题是您正在兑现承诺。 When you put your console.log outside your then() function, you are logging the variable before it has actually been resolved. 当您将console.log放在then()函数之外时,您实际上是记录变量之前对其进行解析。

If you put your console.log inside your then() function (after sitemap is assigned), it should show the correct value, but you still won't be able to access it reliably. 如果将console.log放在then()函数中(分配了站点地图之后),它应该显示正确的值,但是仍然不能可靠地访问它。

I think the simplest way for you to access the siteMap value after it has been populated with data is to pass in a callback function. 我认为,在填充数据访问siteMap值的最简单方法是传递一个回调函数。 Eg: 例如:

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);
    });

You would then use this in your controller like so: 然后,您将在控制器中使用它,如下所示:

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

Now while this will work, it is just one quick example, and not necessarily the best way. 现在,尽管这将起作用,但这只是一个简单的示例,不一定是最佳方法。 If you don't like callbacks, you could create a second promise that resolves only when siteMap is assigned. 如果您不喜欢回调,则可以创建第二个Promise,仅在分配siteMap时解析。 Also depending on your use case for getSiteMap() , you may want to cache the value, otherwise the request will be called every time. 另外,根据您对getSiteMap()使用情况,您可能希望缓存该值,否则将每次都调用该请求。

Try chaining your promises like this: 尝试像这样链接您的诺言:

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
    });
 }

Use it like this: 像这样使用它:

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

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM