AngularJSに現在のユーザーコンテキストを保存するにはどうすればよいですか?


92

ユーザーにログインするAuthServiceがあります。それはユーザーのjsonオブジェクトを返します。私がしたいことは、そのオブジェクトを設定し、ページを更新する必要なく、すべての変更をアプリケーション全体に反映させることです(ログイン/ログアウト状態)。

AngularJSでこれをどのように達成しますか?

回答:


180

これを行う最も簡単な方法は、サービスを使用することです。例えば:

app.factory( 'AuthService', function() {
  var currentUser;

  return {
    login: function() { ... },
    logout: function() { ... },
    isLoggedIn: function() { ... },
    currentUser: function() { return currentUser; }
    ...
  };
});

その後、任意のコントローラーでこれを参照できます。次のコードは、(指定された関数を呼び出すことにより)サービスからの値の変更を監視し、変更された値をスコープに同期します。

app.controller( 'MainCtrl', function( $scope, AuthService ) {
  $scope.$watch( AuthService.isLoggedIn, function ( isLoggedIn ) {
    $scope.isLoggedIn = isLoggedIn;
    $scope.currentUser = AuthService.currentUser();
  });
});

そしてもちろん、その情報は、必要に応じて使用できます。例:ディレクティブ、テンプレートなど。メニューコントローラーなどでこれを(必要に応じてカスタマイズして)繰り返すことができます。サービスの状態を変更すると、すべて自動的に更新されます。

より具体的なものは、実装によって異なります。

お役に立てれば!


28
@ChrisNicola実際、AngularJSではすべてのサービスがシングルトンです。したがって、サービスは最初に要求されたときに(つまり、コントローラーまたは別のサービスによって)作成され、それ以降のすべての要求はまったく同じインスタンスを返します。
Josh David Miller

2
それも可能ですが、関数として、その情報をパブリックAPIからプライベートAPIに格納する方法の内部を削除できます。これにより、後でリファクタリングがはるかに簡単になります。ただし、この関数はブール値を返します。
Josh David Miller、

7
これは馬鹿げた質問かもしれません...しかし、ユーザーがページを更新するとどうなりますか?ログイン情報は失われますか?
トンバ2013年

10
@Tombaいい質問ですね。:-)確かに情報は更新時に失われます。通常、いくつかのセッション情報をCookie に保存します。そのセッション情報は、の設定時にも確認できますAuthService。これは、ページの更新だけでなく、新しいタブでリンクを開く人にも役立ちます。
Josh David Miller

2
@PixMach学習曲線は100%正しいです。あなたの質問は特定のケースの多くに依存することになりますが、ここにいくつかの一般的なパターンがあります。懸念事項の分離を維持する:ログインの開始に関連するUIは、認証の状態とは別の認証自体から分離されています。ナビゲーション/メニューは多くの場合、単一のコントローラーで処理するのが最適です。ネストされた状態(la ui-router)とルート解決は、認証制御をDRYに保つための良い方法です。あなたが書いたものは正しいと思います。
Josh David Miller

5

AuthServiceは通常誰でも関心があるため(つまり、誰もログインしていない場合は、ログインビュー以外はすべて表示されないはずです)、もっと簡単な代替策は、$rootScope.$broadcast('loginStatusChanged', isLoggedIn);(1 )(2)、関係者(コントローラなど)はを使用してリッスンし$scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; }ます。

(1)$rootScopeサービスの引数として挿入される

(2)非同期ログイン操作が発生する可能性が高い場合、Angularに、ブロードキャストを変更して、$rootScope.$apply()関数に含めることで通知する必要があることに注意してください。

ここで、すべての/多くのコントローラーでユーザーコンテキストを維持することについて言えば、すべてのコントローラーでログインの変更をリッスンすることに満足できず、最上位のログインコントローラーでのみリッスンし、他のログイン対応コントローラーを子として追加することを好むかもしれません/これの組み込みコントローラー。このようにして、子コントローラーは、ユーザーコンテキストなどの継承された親$ scopeプロパティを確認できます。


4
ファクトリー機能の誤った説明のために反対票を投じました。この誤解は、回答を投稿する前のこのコメント月ですでに対処されています。
Rhys van der Waerden、2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.