2

$rootScope.foo私のモジュールには、 serviceの使用によって設定される に依存するコントローラーがあり$httpます。私の質問は$rootScope.foo、コントローラーがロードされる前に確実にデータが入力されるようにする方法です。

$rootScope.fooモジュールのrun()メソッドにロードしてみました:

myModule.run(function($rootScope, $http, $location) {
  $http.get("http://mydomain/load_user/").
    success(function(respData) {
      $rootScope.foo = respData.foo;
    });
});

しかし、コントローラーがコード内のコードの前にロードされるため、機能しませんsuccess()

4

1 に答える 1

9

この$httpサービスは promise を使用して実装されます。

successプロミスが解決されると、ハンドラーに記述したコードが実行されます。promise の非同期性のため、これがいつ発生するかは不明です。1秒後でも10秒後でも構いません。

その間、他のコードは引き続き実行され、promise が解決される前にコントローラーがロードされる可能性があります。

この問題に取り組む最善の方法は、ある種の同期動作を強制するのではなく、「非同期」の用語で考えることです。

いくつかの有効なオプションを次に示します。

  1. 次のように、コードをコントローラーに移動し、ロジックを成功ハンドラーに移動できます。

    myModule.controller('SomeCtrl', function($rootScope, $http, $location) {
      $http.get("http://mydomain/load_user/").
        success(function(respData) {
          // Perform any logic you need here and use respData.foo;
        });
    });
    
  2. もう 1 つの方法は、イベントを使用して、次のように promise が解決されたとき (およびデータがサーバーから読み込まれたとき) にコントローラーに通知することです。

    myModule.run(function($rootScope, $http, $location) {
      $http.get("http://mydomain/load_user/").
        success(function(respData) {
          $rootScope.foo = respData.foo;
    
          // Broadcast event that foo was updated
          $rootScope.$broadcast('fooWasUpdated'); 
        });
    });
    

    次に、コントローラーでイベントのリスナーを追加できます。

    myModule.controller('SomeCtrl', function($scope, $rootScope) {
    
      $scope.$on('fooWasUpdated', function(event){
        // Perform your logic with $rootScope.foo
      });
    
    });
    
  3. 3 つ目の方法は、 をまったく使用せずに$rootScope、イベントを使用してリスナーに通知し、次のようにイベントでデータを渡すことです。

    myModule.run(function($rootScope, $http, $location) {
      $http.get("http://mydomain/load_user/").
        success(function(respData) {
          // Broadcast event that foo was updated
          // You can add data as extra arguments
          $rootScope.$broadcast('fooWasUpdated', respData.foo); 
        });
    });
    

    次に、コントローラーでイベントのリスナーを追加できます。

    myModule.controller('SomeCtrl', function($scope, $rootScope) {
    
      $scope.$on('fooWasUpdated', function(event, foo){
        // Perform your logic with foo instead of $rootScope.foo
      });
    
    });
    

    $broadcastおよびスコープに関する AngularJS のドキュメント$onで、より詳細な情報を見つけることができます。

イベントを使用する利点は次のとおりです。

  • 同じイベントをリッスンするアプリケーションに複数のリスナーを含めることができます
  • AngularJS で適切なスコープにいることを心配する必要はありません
  • 他の場所で使用できるようにするために、必ずしもデータをスコープに保存する必要はありません

それが役立つことを願っています!

于 2013-07-03T22:46:01.730 に答える