无法从控制器中的服务访问数据

时间:2014-10-30 07:52:50

标签: angularjs angularjs-scope angularjs-service

我正在尝试将angular-typeahead添加到我的应用中以获取搜索建议,并从此Plunkr获取帮助。

这是app.js文件的代码:

var myApp = angular.module('myApp', ['ngRoute','siyfion.sfTypeahead']);

myApp.factory('websitesSvc',function($http, $log, $q) {
return {
    getwebsites: function(){

        //Create a promise using promise library
        var deferred = $q.defer();

        $http({method: 'GET', url: '/api/websites/'}).
            success(function(data, status, headers,config){
                deferred.resolve(data);
            }).
            error(function(data, status, headers,config){
                deferred.reject(status);
            });

        return deferred.promise;
    }
};
});

myApp.controller('MyCtrl', ['$scope','websitesSvc',
function($scope,websitesSvc) {

$scope.searchString=null;


websitesSvc.getwebsites().then(function(websites){
 $scope.websites = websites;
 console.log($scope.websites); //It works here
}); 

//Output undefined
//THIS IS NOT WORKING

console.log($scope.websites); 



var websites = new Bloodhound({
datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.domain_name); },
queryTokenizer: Bloodhound.tokenizers.whitespace,

//want to pass the websites array list from service to local 
local:websites, //THIS IS NOT WORKING
});

// initialize the bloodhound suggestion engine
 websites.initialize();

$scope.numbersDataset = {
displayKey: 'domain_name',
 source: websites.ttAdapter()
};

// Typeahead options object
$scope.exampleOptions = {
 highlight: true
}; 

 }
]);

问题是我无法将$scope.websites的值传递给typeahead。如何从服务中获取网站的价值,以便我可以将结果数组传递给{ {1}}?

按照红色建议编辑代码6小时前Kalhano Toress Pamuditha,我可以访问数据。但是现在我得到了这个Console Error

1 个答案:

答案 0 :(得分:1)

websitesSvc.getwebsites().then(function(websites){
   $scope.websites = websites;
   console.log($scope.websites); //It works here
});


//Output undefined
//THIS IS NOT WORKING

console.log($scope.websites);                 this will execute before   websitesSvc.getwebsites() completes,

javascript代码在同步调用完成之前不会保持,它将执行其余的代码,即你得到未定义的情况。

您将在websitesSvc.getwebsites()承诺后获得数据。因此,如果您需要在收到此数据后执行某些操作,您可以在then内部执行一项功能,如下所示

  websitesSvc.getwebsites().then(function(websites){
     $scope.websites = websites;
     console.log($scope.websites); //It works here
     $scope.methodAfterComplete();
 });  
 $scope.methodAfterComplete = function() {
     // this will call after completing the websitesSvc.getwebsites()
 }      

因此您可以将代码放在需要methodAfterComplete数据的$scope.websites方法中。例如;

 $scope.methodAfterComplete = function() {
     var websites = new Bloodhound({
       datumTokenizer: function(d) { return Bloodhound.tokenizers.whitespace(d.domain_name); },
        queryTokenizer: Bloodhound.tokenizers.whitespace,
               local:websites,
       });

      // initialize the bloodhound suggestion engine
       websites.initialize();

     $scope.numbersDataset = {
     displayKey: 'domain_name',
      source: websites.ttAdapter()
    };

    // Typeahead options object
     $scope.exampleOptions = {
        highlight: true
     }; 
 }