4

我有类似的工厂,里面有 $http 调用,如下所示:

appModule = angular.module('appModule', []);

appModule.factory('Search', function($rootScope, $http) {
  var Search;
  Search = {};
  Search.types: ["bacon"];
  Search.pastEvents = null;
  $http.get('api/highlights').success(function(response) {
    return Search.pastEvents = response.data;
  });
  return Search;
});

var notes_module = angular.module('notes', []);

notes_module.config(['$routeProvider', function ($routeProvider) {

  var notes_promise = ['Notes', '$route', 'Search', function (Notes, $route, Search) {
    //suspect that Search not having pastEvents ready in time of calling index method
    //Notes resource  
    return Notes.index({subject_id: 1 }, Search);    
  }];

  $routeProvider.when('/notes', {
    templateUrl:'index.tpl.html',
    controller:'NotesCtrl',
    resolve:{
      notes: notes_promise,
    }
  });

}]);

我是否应该关心来自 $http 调用的数据何时准备好以及何时初始化/注入该工厂?过去的活动准备好了吗?如果我应该关心我该怎么办?

我怀疑 Search 对象在调用 Notes 资源的 index 方法时没有准备好过去的事件。

4

1 回答 1

5

这取决于:

如果您立即放入 in$scope以使用,例如在 a 中ng-repeat,则不会。

如果您需要控制器中的另一个功能,那么可以。例如,如果您pastEvents在控制器上使用您的过滤器功能。在这种情况下,最好将所有操作保留在您的服务内部,并用于$q解决异步谜题。

(这只是一个例子)

appModule.factory('sharedApplication', function($rootScope, $http, $q) {
  var deferred = $q.defer();

  $rootScope.$on('data:loaded', function(e, data) {
    deferred.resolve(data);
  });

  return {
     getApp: function(filter) {
        if (!filter) { filter = function() { return true; } }

        var filtered = {};
        deferred.promise.then(function(data) {
           filtered.pastEvents = _.filter(data, filter); 
        };
        return filtered;
     }
  };
});

一点解释。数据随服务中的事件到达。那时getApp()可能已经被调用了。但这没关系,因为$q将确保数据仅在稍后到达时才会被过滤。控制器不需要知道这一点,只要它不尝试执行以下操作:

$scope.app = service.getApp();
for(var i = 0; i < $scope.app.pastEvents.length; i++) {
   ...
} 

如果您确实需要评估控制器中的内容,请使用$scope.$watch(),例如:

$scope.$watch('app', function(value) {
   ...
}, true);

编辑:

在我看来,当您在您的以下Search位置使用它时,您的情况尚未解决$routeProvider

Notes.index({subject_id: 1 }, Search)

因此,请尝试解决并在控制器中Search使用您的Notes资源。

您需要在Search服务中兑现承诺。两种选择:

  • 返回 $http 承诺,但这可能不是你想要的,如果你需要先对数据做一些事情
  • 使用 $q 并返回它的承诺

$q 示例:

appModule.factory('Search', function($rootScope, $http, $q) {
  var deferred = $q.defer();
  $http.get('api/highlights').success(function(response) {
    deferred.resolve({
       type: ["bacon"],
       pastEvents: response.data)};
  });
  return deferred.promise;
});
于 2013-01-10T18:17:37.747 回答