我有一个由一些控制器调用的工厂。
app.factory('fileData', function($http) {
return {
get: function(filename){ return $http({ method: 'GET', url: filename});
}
};
});
现在我想从常规函数调用它并从工厂返回数据。我怎样才能做到这一点?这个不起作用,因为传入的fileData在没有$ scope的情况下无法识别。
function getData (file, fileData) {
rels = [];
var handleSuccess = function(data, status) {
rels = data;
console.log(rels);
};
fileData.get(filename).success(handleSuccess);
return rels;
}
知道如何解决这个问题吗?
答案 0 :(得分:0)
您对工厂中公开的方法的调用(get
)使用返回承诺的$http
服务。因此,您无法以同步方式获得此调用的结果。
在您的示例中,return rels
在调用handleSuccess方法之前发生,因此您将返回旧值(空数组)。
它在控制器功能内部工作的原因是控制器实例存活的时间较长,当服务器调用成功返回时,控制器的$scope
中的变量被分配(然后反映在您的UI通过角度数据绑定)。
因此,解决此问题的最佳方法是避免在“常规函数”中使用同步api。你可以通过返回一个承诺来使这也变得异步吗?
答案 1 :(得分:0)
在return rels
内移动handleSuccess
,您将在handleSuccess
被调用之前返回。所以你发信号表示该功能过早地完成了执行。
function getData (file, fileData) {
rels = [];
var handleSuccess = function(data, status) {
rels = data;
console.log(rels);
return rels; // Return rels when the Promise is finished
};
fileData.get(file).success(handleSuccess);
}
由于您从$http
返回了承诺,因此您需要以异步方式处理其执行,直到承诺得到解决后才会返回。
添加reject
处理程序也是一个好主意。
请参阅下文,了解使用$http
fileData.get(file)
.then(handleSuccess)
.catch(handleFailure); // Handle any errors returned from $http
编辑更新控制器的DI示例
您需要将fileData
工厂注入Angular Controller。有关依赖注入的更多信息,请参阅Angular Docs for DI。需要注意的是,DI是一个巨大的Angular,因此在继续之前了解这一点非常基础。
angular
.module('yourApp')
.controller('yourController', ['$scope', 'fileData', function($scope, fileData) {
// Expose getData via $scope
$scope.getData = getData;
function getData(file, fileData) {
var rels = [];
var handleSuccess = function(data, status) {
rels = data;
console.log(rels);
return rels;
};
fileData.get(file)
.then(handleSuccess);
}
}]);