Angular JS /文章没有定义

时间:2016-11-01 10:13:27

标签: javascript angularjs

我在Angular App中的services.js中有这段代码:

.factory('Articles', function($http) {

  $http.get('https://api.myjson.com/bins/4ici6').then( function(response) {
      var articles = response.data.articles;
  });

  return {
    all: function() {
      return articles;
    },
    get: function(articleId) {
      for (var i = 0; i < articles.length; i++) {
        if (articles[i].id === parseInt(articleId)) {
          return articles[i];
        }
      }
      return null;
    }
  };
})

当我在控制台中收到此错误时,它无法正常工作:

ReferenceError: articles is not defined
    at Object.all (http://localhost:8100/js/services.js:31:14)
    at new <anonymous> (http://localhost:8100/js/controllers.js:4:30)
    at Object.instantiate (http://localhost:8100/lib/ionic/js/ionic.bundle.js:18015:14)

此处还有引用controller.js的{​​{1}}代码:

articles

我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

因为$http.get是异步调用,所以您必须处理它。

只要把它放在工厂的顶部就不会一直工作。

请改为尝试:

.factory('Articles', function($http) {

  return {
    all: function() {
      return  $http.get('https://api.myjson.com/bins/4ici6').then(function(response) {
        return response.data.articles;
      });
    },
    get: function(articleId) {
      //Probably best here to call an API endpoint that will return a single article with the parameter's articleId
      //Something along the lines of 
      //$http.get('https://api.myjson.com/bins/4ic16/' + articleId).then(function(response) { //handle response});
    }
  };
})

您的控制器也应该更改为处理异步函数调用:

.controller('NewsCtrl', function($scope, Articles) {
  Articles.all().then(function(articles) { $scope.articles = articles });
})

答案 1 :(得分:1)

你在http的回调中声明了你的文章变量,所以它不会在它之外可用。将它移到外面:

.factory('Articles', function($http) {

    // declaring it here makes it available in the 'all' function
    var articles = [];

    $http.get('https://api.myjson.com/bins/4ici6').then( function(response) {
        articles = response.data.articles;
    });

    return {
        all: function() {
            return articles;
        },
        get: function(articleId) {
            for (var i = 0; i < articles.length; i++) {
                if (articles[i].id === parseInt(articleId)) {
                    return articles[i];
                }
            }
            return null;
        }
    };
})

但是因为您通过http异步获取文章,所以在获取文章之前执行Articles.all() 之前可能会发生这种情况,从而导致数组为空。相反,我会这样做:

.factory('Articles', function($http, $q) {

    // declaring it here makes it available in the 'all' function
    var articles = [];
    var fetched = false;

    var getAll = function() {
        var deferred = $q.defer();
        if (!fetched) {
            $http.get('https://api.myjson.com/bins/4ici6').then( function(response) {
                articles = response.data.articles;
                fetched = true;
                deferred.resolve(articles);
            });
        } else {
            deferred.resolve(articles);
        }
        return deferred.promise;
    }

    return {
        all: getAll,
        get: function(articleId) {
            var deferred = $q.defer();
            getAll().then(function(articles) {
                for (var i = 0; i < articles.length; i++) {
                    if (articles[i].id === parseInt(articleId)) {
                        deferred.resolve(articles[i]);
                        break;
                    }
                } 

                // not found
                return deferred.reject();
            }
            return deferred.promise;
        }
    };
})

并像这样使用它:

Articles.all().then(function(articles){
    // now the articles are available
});

Articles.get(id).then(function(article){
    // found   
}, function(){
    // not found
});