如何使控制器等待服务返回值以及如何访问控制器中的返回值?

时间:2015-02-17 12:44:14

标签: angularjs node.js angularjs-scope firebase firebasesimplelogin

我是 angularjs 的新手。我无法访问从其控制器中的angularjs服务返回的以下是控制器中的代码:

'use strict';
app.controller('AdminTaskCtrl', function ($scope, Search) {
    $scope.buildEnquiry = function (collegeId, ) {
        Search.getIdByEmail(collegeId).then ( function ( result ) {
            $scope.uId = result;
            console.log($scope.uId);
        });
    };
});//controller ends here

搜索服务中的代码如下:

'use strict';
           app.factory('Search',function ($firebase, FIREBASE_URL, $rootScope) {
                          var simpleuser = "";
                          getIdByEmail: function(counsellorEmail) {
                          var collegeuserArray = ($firebase(new Firebase(FIREBASE_URL+"abc/def/")).$asArray());
                          collegeuserArray.$loaded(function(collegeuserArray) {
                              for(var i=0; i<collegeuserArray.length; i++) 
                              {
                                if((collegeuserArray[i].$value) == counsellorEmail)
                                {
                                     simpleuser = collegeuserArray.$keyAt(collegeuserArray[i]);
                                     console.log(simpleuser);
                                     return simpleuser;
                                }
                              }
                          }, function(error) {
                              console.error("Error:", error);
                          });
                    }
                  };     
            );//service ends here.

当代码执行时,它会将.then函数的错误视为休闲:

TypeError:undefined不是函数,并且不会访问控制器中的值。

请帮忙。

2 个答案:

答案 0 :(得分:4)

'use strict';
       app.factory('Search',function ($firebase, FIREBASE_URL, $rootScope, $q) {
                      var simpleuser = "";
                      getIdByEmail: function(counsellorEmail) {
                      var deferred = $q.defer();
                      var collegeUserArray = ($firebase(new Firebase(FIREBASE_URL+"abc/def/")).$asArray());
                      collegeUserArray.$loaded(function(collegeUserArray) {
                          for(var i=0; i<collegeUserArray.length; i++) 
                          {
                            if((collegeUserArray[i].$value) == counsellorEmail)
                            {
                                 simpleUser = collegeUserArray.$keyAt(collegeUserArray[i]);
                                 console.log(simpleUser);
                                 //return simpleUser;
                                 deferred.resolve(simpleUser);
                            }
                          }
                      }, function(error) {
                          console.error("Error:", error);
                          deferred.reject(error);
                      });
                      return deferred.promise;
                }
              };     
        );

和你的控制器

'use strict';
app.controller('AdminTaskCtrl', function ($scope, Search) {
  $scope.buildEnquiry = function (collegeId, ) {
    Search.getIdByEmail(collegeId).then ( function ( result ) {
        $scope.uId = result;
        console.log($scope.uId);
    }, function(error){
        //If an error happened, handle it here
    });
  };
});

答案 1 :(得分:1)

要直接回答您的问题$loaded returns a promise,所以这里最简单的答案就是将其从您的服务中退回,而不是使用$ q和其他所有其他事情。

看起来这里的整个前提似乎是有缺陷的,而且这是一个XY problem。似乎有几个hacks旨在颠覆这些libs的预期用法,就像对Angular walkthroughAngularFire guide的良好,可靠的阅读一样,这将节省很多痛苦和不必要的复杂性。

这里工厂的使用是一种颠覆和严重耦合。语法无效,无法编译。最终,目标是为AngularFire返回的synchronized数组添加一个搜索方法,该方法应该使用$ extendFactory。

app.factory('firebaseRef', function(FIREBASE_URL) {
   return function(path) {
      var ref = new Firebase(FIREBASE_URL);
      if( path ) { ref = ref.child(path); }
      return ref;
   }
});

app.factory('SearchableArray', function($firebase, $FirebaseArray) {
   var ArrayWithSearch = $FirebaseArray.$extendFactory({
     searchByEmail: function(emailAddress) {
        var res = null;
        for(var i=0, len=this.$list.length; i < len; i++ ) {
           if( this.$list[i].email === emailAddress ) {
              res = this.$list[i];
              break;
           }
        }
        return res;
     }
   });

   return function(ref) {
      return $firebase(ref, {arrayFactory: ArrayWithSearch}).$asArray();      
   }
});

app.controller('Controller', function($scope, SearchableArray, firebaseRef) {
   $scope.data = SearchableArray( firebaseRef('abc/def') );

   $scope.search = function(email) {
      console.log( $scope.data.searchByEmail(email) );
   };
});