web-dev-qa-db-ja.com

Angular httpは$$ stateオブジェクトを返します

次のファクトリーを定義しています:

angular.module("account").factory("users",["$http",
    function(a){
      return {
         getUser: function(){
            return a.get("/user/me").then(function(r){
                return r.data;
            });
        }
    };
  }
]);

そして私のコントローラー:

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        a.user = u.getUser();
        console.log(a.user);
}]);

Console.logは次のとおりです。

 d {$$state: Object, then: function, catch: function, finally: function} $$state: Object status: 1 value: Object user: Object__v: 0 _id: "54c1fg29f36e117332000005" temp: "1ce3793175e0b2548fb9918385c2de09"  __proto__: Object __proto__: Object __proto__: Object __proto__: Object

上記のコードは、ユーザーオブジェクトの代わりに状態オブジェクトを返しています。ただし、ログからは、状態オブジェクトにはvalue内にユーザーオブジェクトがあります。ユーザーオブジェクトを取得するにはどうすればよいですか?それとも私はこれを完全に間違っていますか?

他の方法は$ http.getを返し、コントローラー内でthen()メソッドを呼び出すことです。しかし、私はユーザーオブジェクトを頻繁に使用し、コントローラーでthen()メソッドを呼び出す場合は、ファクトリーの代わりにコントローラーで$ http.getを使用するのとほぼ同じです。

16
wdphd

JavaScript I/Oは通常、この場合非同期を含めます。 getUser呼び出しは、$ qpromiseを返します。ラップを解除するには、チェーンしてから、次のように展開する必要があります。

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        u.getUser().then(function(user){
            a.user = user;
            console.log(a.user);
        });
}]);

ルーティングを使用している場合は、ルートのresolveオプションも調べてください。 この関連する質問 も参照してください。

25
angular.module("account").factory("users",["$http",
    function(a){
      var factObj = {
         user: null,
         getUser: function(){
            return a.get("/user/me").then(function(r){
                factObj.user = r.data;
            });
        }
      factObj.getUser();

      return factObj;
    };
  }
]);

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        a.userService = u;
}]);

あなたの意見では

<div ng-controller="TestCtrl as test">{{test.userService.user}}</div>

コメントに基づいて編集します。これはおそらくコントローラーやビューではうまくいかないでしょうが、このパターンはうまく機能し、データを再利用する可能性のあるすべてのコントローラーに.thenを使用する必要がなくなります。

通常、データのフェッチを処理するファクトリまたはサービスにモデルを保存すると、必要なすべてのビューにデータを取得するための簡単なパスが作成されます。ここでの欠点は、コントローラからgetUser関数を明示的に起動する代わりに、このファクトリが参照されるときにユーザーを取得することです。回避したい場合は、getUser関数で最初に要求されたときからプロミスを保存し、既に設定されている場合は後続のすべての呼び出しに対してそのプロミスを返すことができます。この方法では、API要求を繰り返さずにgetUserを複数回呼び出すことができます。

2
shaunhusain

ここにも同様のシナリオがあります。誰かに役立つことを願っています...

私の工場..

 angular.module('programList.services',[])
    .factory('PROGRAMS', function($http) {
     return {
       getprogramList: function() {
       return $http.get('/api/programs/list').then(function(result) {
       return result.data[0];
       });
      }
     };
    });

これは私のコントローラーです..

 angular.module('programList.services'])
 .controller('tviProgramsController',
    function($scope,$state,$stateParams,PROGRAMS){
        //this is the call to access the list as answered by Benjamin Above using then on success 
        PROGRAMS.getprogramList().then(function(list){
                  $scope.programlist = list;
              });
  });

;

これはサーバー側のルーターにあります...

  var express     = require('express'),
     programscontroller = require(path + 'programservercontroller'),
     router         = new express.Router();
     router.get('/api/programs/list', programscontroller.programlist);

これはmysql呼び出しのモジュールです

var con   = require('../../database/dbcon'),
mysql = require('mysql');

module.exports.programlist = function(req, res){
 var data = req.params.data;
 var sql = "CALL `sp_programlist`";
  con.query(sql, function(err, result) {
      if(err){
          throw err;
      } else {
          res.send(JSON.stringify(result));
      }
     });
};
0
sireken