20

私の質問は、Angular Google グループのこのトピックに基づいています。
$http を介してバックエンドから取得した基本データを保存するサービスを提供したいので、それらのデータを 1 回フェッチするだけで済みます。お気に入り、

var load = function() {
   return $http.get(...).then(function(data) {
       return data.user; 
   });
};

module.factory("userProvider", function() {
    var user;
    var getUser = function() {
        if(!user) {
            load().then(function(data) {
               user = data;
           });
        }
        return user;
    };
    return {
        getUser : getUser
    }
});

module.controller("UserController", ["userProvider", function UserController("userProvider") {
    var user = userProvider.getUser();
    // do something with user
}]);

問題は、Promise チェーンがコントローラーではなく userProvider で終了するため、データが返されていないため、このコントローラーを初めて使用するときにユーザーが未定義になることです。

このようなストレージ サービスを使用して、データを正しく返すにはどうすればよいですか? ありがとう!

4

2 に答える 2

19

自分だけの約束を作ることができます。変更されたコードは次のとおりです。

module.factory( "userProvider", function( $q ) {
  // A place to hold the user so we only need fetch it once.
  var user;

  function getUser() {
    // If we've already cached it, return that one.
    // But return a promise version so it's consistent across invocations
    if ( angular.isDefined( user ) ) return $q.when( user );

    // Otherwise, let's get it the first time and save it for later.
    return whateverFunctionGetsTheUserTheFirstTime()
    .then( function( data ) {
      user = data;
      return user;
    });
  };

  // The public API
  return {
    getUser: getUser()
  };
});

更新: @yohairosen による以下の解決策は、多くの状況に適していますが、すべての状況に適しているわけではありません。ここで行ったように、状況によっては、成功した結果のみをキャッシュしたい場合があります。たとえば、このリクエストの失敗がユーザーが最初にログインする必要があることを示している場合、次の呼び出し (おそらくログイン後) でキャッシュされた失敗を配信したくありません。メソッドがすべての状況で call-to-call から必ずしも一貫しているとは限らない場合は、このメソッドの方が優れています。それ以外の場合は、@yohairosen のソリューションがよりシンプルで推奨されます。

于 2013-01-15T07:48:35.467 に答える