在ajax-load之后,广播数据从服务变为多个控制器

时间:2015-07-27 20:22:19

标签: javascript angularjs pointers scope

我有角度服务,从服务器加载数据,有些控制器依赖于这个服务(它们使用通过服务加载的数据)。但是数据由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"修改数组。并且"推",但这非常"脏"方式。

1 个答案:

答案 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 ....