我有一个工厂函数,它不会返回我想在控制器中设置的变量。我没有得到错误,只是变量不会被设置为它所设想的。
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
}
});
答案 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){
});