2013-08-22 11 views
6

これは、これが私がやっていることを達成するための最良の方法であるかどうか、本当に分かりません。1つのAngularJSコントローラが別のものより先にロードされるようにする

OAUTH2を使用しているユーザーアカウントシステムで、データベースのユーザー情報を参照し、変数として保存します($rootScope.userInfo)。これは私のアプリのbodyに追加されたコントローラにあります。ここでは、最高レベルのコントローラがその中にあるものの前にロードされると思っていましたが、明らかにそうではありません。

は、私は私のデータベースからそれをロードする機会があった私のmainCtrl前にこの$rootScope.userInfoオブジェクトにアクセスしようとしたビューをロードした場合、それはjavascriptのエラーとAngular休憩をスローします。

参考のため、ここではテンプレートの目安です:私はこのようなmainCtrl$rootScope.userInfoをロードしています

<body ng-controller="mainCtrl"> 
    <header>Content</header> 
    <div class='main-view' ng-controller="userProfile"> 
     <p>{{user.name}}</p> 
     <p>{{user.email}}</p> 
    </div> 
</body> 

:私のuserProfile制御に続いて

$http.get('/api/users/' + $cookies.id). 
    success(function(data) { 
     $rootScope.userInfo = data.user[0]; 
     console.log("User info is:"); 
     console.log($rootScope.userInfo); 
     $scope.status = 'ready'; 
    }); 

、私が行います

function userProfile($scope, $cookies, $http, $routeParams, $rootScope){ 
    if($scope.status == 'ready'){ 
    $scope.user = $rootScope.userInfo; 
    console.log("Double checking user info, here it is:"); 
    console.log($rootScope.userInfo); 
    } 
} 

私がアプリ内の別のページから来ている場合は、wh ichは$rootScope.userInfoを呼び出さず、APIはそれを調べるのに十分な時間があり、userProfileページは正常に動作します。しかし、フルページのリフレッシュを実行すると、$rootScope.userInfoにロードする時間がなくなり、エラーが発生します。

どうすればこの問題を解決できますか?

答えて

14

あなたが記述した問題は、$rootScopeを使用してコントローラ間でデータを共有することをお勧めしない理由の1つです。つまり、2つのコントローラ間に手作業による "不可視"の依存関係が作成されます。他のコントローラはまだありません。

ユーザーのロジックをロードするロジックを、たとえばuserProfileServiceなどのサービスに移動して、両方のコントローラに注入することをお勧めします。それは一度作成され、両方のコントローラに使用されます。そのようなサービスでは、コントローラが要求したときに$httpというユーザプロファイルをロードし、次のときにキャッシュから返すことができます。このように、依存関係は、コントローラ間ではなく、両方のコントローラから共有サービスに移行します。

私はAngularJSのドキュメントの巨大なファンではありませんが、DI,Creating Services、およびInjecting Servicesのように役に立ちます。

+0

これはかなり近いです、私はサービスとしてそれを使用する考えが好きです。しかし、ローディングオーダーの問題は解決しません。私はサービスをセットアップしましたが、サービスがデータを返す前にコントローラをロードしています!アイデア? – Jascination

+0

私はここで更新された質問をしました:http://stackoverflow.com/questions/18477711/force-angularjs-service-to-return-data-before-loading-controller私はこれを答えとして受け入れます仕事のほとんどは、その1つにも答えてください。 – Jascination

0

代わりに、成功の使用thenng-includeを使用して、子コントローラの読み込みを遅らせる:mainCtrl内部

<div class='main-view' ng-controller="userProfile"> 
    <p>{{user.name}}</p> 
    <p>{{user.email}}</p> 
</div> 

コールバック:

<body ng-controller="mainCtrl"> 
    <header>Content</header> 
    <ng-include src="templatePath"></ng-include>   
</body> 
は、新しいテンプレート userprofile.html内のHTMLを移動

$http.get('/api/users/' + $cookies.id). 
    then(function(data) { 
     /* mainCtrl being the parent controller, simply exposing the 
      properties to $scope would make them available 
      to all the child controllers.*/ 
     $rootScope.userInfo = data.user[0]; 
     /* assign the template path to load the template and 
      instantiate the controller */ 
     $scope.templatePath = "userprofile.html"; 
    }); 
+0

'$ http.success(foo)'はすべての引数を正しく渡す '$ http.then(foo)'のエイリアスです。「成功」から「その後」に変わるものは何でしょうか? [ソース](https://github.com/angular/angular.js/blob/master/src/ng/http.js#L673)を参照してください。 –

+0

@stevuuうん。 1つをもう一方の上に使用することには意味がないようです。 – AlwaysALearner