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

我是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 

search服务中的代码如下所示:

 '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不是函数 ,控制器中的值不被访问。

请帮忙。

 '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 }); }; }); 

为了直接回答你的问题, $loaded 返回一个promise ,所以这里最简单的答案就是从你的服务中返回它,而不用麻烦$ q和所有这些其他的东西。

看来这里的整个前提是有缺陷的,这是一个XY问题 。 似乎有几个黑客打算颠覆这些库的预期用法,就像Angular walkthrough和AngularFire的一个很好的,坚实的阅读指南将节省很多的痛苦和不必要的复杂性在这里。

在这里工厂的使用是一个颠覆和严重耦合。 该语法是无效的,不会编译。 最终目标是将search方法添加到从AngularFire返回的同步数组中,这应该使用$ 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) ); }; });