我有角度服务,从服务器加载数据,有些控制器依赖于这个服务(它们使用通过服务加载的数据)。但是数据由ajax-request加载(并且它是异步的),并且控制器检索指向任何数组的指针,并在ajax-request完成后由另一个加载的数组替换。服务在数组上有实际指针,而控制器没有。
以下是一些带注释的代码:
angular.module('someApp')
.factory('operationService', ['$http', function($http){
// now, after app started, some controllers will receive pointer to this empty array
var operations = [];
$http.get('some-link').success(function(data){
// controllers have some pointer to old array, but we replace variable
// controllers have old array, not loaded from server
operations = data;
});
return {
// controllers will take pointer via this method
getOperations: function () {
return operations;
}
};
}])
.controller('SomeController', ['$scope', 'operationService', function($scope, opService){
// here we receive empty array
$scope.operations = opService.getOperations();
// and sometimes, when ajax-request will be finished, we still have empty array :(
}]);
什么是"最佳实践"在角度应用程序中到处都有实际数据?我知道,我可以使用" splice"修改数组。并且"推",但这非常"脏"方式。
答案 0 :(得分:1)
有几种方法可以只进行一次http调用,但是我只能通过我们在这里使用的软件版本来实现这一点。
您可以使用承诺或将您的http请求设置为仅发生一次。但是,http设置仅适用于Angular的更高版本。检查你的版本。
至于最佳做法使用您的堆栈允许没有任何方法可以做任何事情。异步操作的最佳实践包括(但不限于)回调,承诺,HTTP设置,最重要的是 - 在当前堆栈配置中有效。
以下工厂代码使用自己的方式管理相同数据的多个回调。在第一次调用之后,任何后续工厂调用都会点击callbackStack并堆积,直到 HTTP 请求返回数据。然后每个回调将触发并获取数据。
angular.module('someApp').factory('operationService', ['$http', function($http){
var callbackStack = [];
var firstCallMade = false;
var factoryServerData;
return {
getOperations: getOperations
};
function getOperations( ctrlCallback ){
callbackStack.push( ctrlCallback );
if( firstCallMade ){ return; }
firstCallMade = true;
getOperationsHttpRequest();
};
function getOperationsHttpRequest(){
$http.get('some-link').success( factoryCallback );
}
function factoryCallback( operations ){
// handle !operations here if you need to.
factoryServerData = operations || null;
callbackStack.forEach( giveCtrlCallbackResponse );
}
function giveCtrlCallbackResponse( ctrlCallback ){
ctrlCallback( factoryServerData );
}
}]);
通过在每个控制器中使用回调,您将确保获得http调用返回的任何内容。您仍将获得一个空数组,但前提是服务器返回的数组不是因为控制器加载的异步问题。
.controller('SomeController', ['$scope', 'operationService', function($scope, opService){
opService.getOperations( getOperationsCallback );
// Now $scope.operations will wait until your server responds.
function getOperationsCallback( response ){
$scope.operations = response;
}
}]);
.controller('SomeOtherController', ['$scope', 'operationService', function($scope, opService){
opService.getOperations( getOperationsCallback );
// Now $scope.operations will wait until your server responds.
function getOperationsCallback( response ){
$scope.operations = response;
}
}]);
注意如果您使用嵌套控制器,则第一个控制器可以进行调用,然后将结果广播到所有嵌套控制器。你会用范围来捕捉它。$ on ....