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呼び出しからのデータの準備ができたとき、およびこのファクトリが初期化/注入されたときを気にする必要がありますか?pastEventsは準備ができていますか?どうすればいいですか?

Notesリソースのindexメソッドを呼び出すときに、SearchオブジェクトにpastEventsの準備ができていないのではないかと思います。

4

1 に答える 1

5

場合によります:

$scopeたとえば、で使用するためにすぐに配置する場合は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。2つのオプション:

  • $ 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 に答える