【问题标题】:Factory not passing $http.get based object array to controller in angular.js工厂没有将基于 $http.get 的对象数组传递给 angular.js 中的控制器
【发布时间】:2015-03-06 22:55:44
【问题描述】:

我刚刚开始使用 Angular,并且在某个问题上被困了一段时间。

我的工厂正在正确创建一个包含对象、RSS 提要数据的数组,并将加载到控制台。问题是我似乎无法让数组返回控制器。

任何帮助将不胜感激。请原谅粗糙和草率的代码。

Main.js

function FeedCtrl($scope, GetFeed) {

    $scope.itemId = 0;
    //$scope.items = [];

    console.log('Get episodes in ctrl');
    $scope.items = function() {
        return GetFeed.getEpisodes();
    };
    console.log('display items from ctrl');
    console.log($scope.items());

  $scope.itemId = function(index) {
    $scope.itemId = index;
    console.log($scope.itemId);
    console.log($scope.itemNames[$scope.itemId].title);
  };

};

function EpisodeCrtl($scope, GetFeed) {
    //getFeed.pullFeed();
};

function GetFeed($http){

var episodeArray = [];

function items(){
   console.log('Firing pullFeed');
return $http.get('assets/feed.xml').then(function(response) {
    var x2js = new X2JS()
    var itemDef = x2js.xml_str2json(response.data);
    itemsObj = itemDef.rss.channel.item;

    var numOfItems = itemsObj.length;
    episodeArray.length = 0;
    for (var i = 0; i < numOfItems; i++) {
      episodeArray.push({
        title: itemsObj[i].title,
        link: itemsObj[i].link,
        author: itemsObj[i].author,
        pubDate: new Date(itemsObj[i].pubDate),
        summary: itemsObj[i].summary,
        duration: itemsObj[i].duration,
        description: itemsObj[i].description
      });
    }

    console.log(episodeArray);
    return episodeArray; 
  })
 };

 return {
    getEpisodes: function(){
      console.log(episodeArray);
      episodeArray.length = 0;
      items();
      console.log(episodeArray);
      return(episodeArray);
    }
 }
};

var app = angular.module('ctApp', ['ngMaterial', 'ngAnimate', 'ngRoute'])
.config(function($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'list.html',
            controller: 'FeedCtrl'
        })
        .when('/about', {
            templateUrl: 'about.html',
           controller: 'EpisodeCrtl'
        });
})
.config( [ '$compileProvider', function( $compileProvider ) {
        var currentImgSrcSanitizationWhitelist = $compileProvider.imgSrcSanitizationWhitelist();
        var newImgSrcSanitizationWhiteList = currentImgSrcSanitizationWhitelist.toString().slice(0,-1)
        + '|chrome-extension:'
        +currentImgSrcSanitizationWhitelist.toString().slice(-1);
    }
])
.factory('GetFeed', GetFeed)
.controller('FeedCtrl', FeedCtrl)
.controller('EpisodeCrtl', EpisodeCrtl);

【问题讨论】:

    标签: javascript angularjs angularjs-directive google-chrome-app


    【解决方案1】:

    您需要了解异步调用和承诺的工作原理。一开始你似乎做对了——你在$http.get调用上做return——这会返回承诺。您正在 .then 处理程序中对 episodeArray 执行 return。这是正确的。

    但是,那么,在下面的函数定义中:

    getEpisodes: function(){
          console.log(episodeArray);
          episodeArray.length = 0;
          items(); // this returns immediately and does not yet have the data
          console.log(episodeArray);
          return(episodeArray);
    })
    

    items 的调用立即返回。 episodeArray 仍然是空的。你返回空数组对象[]

    所以,您需要 return items() - 这将返回与 $http.get().then() 所做的相同承诺。

    getEpisodes: function(){
          return items();
    })
    

    那么您不能只将返回值分配给$scope.items - 在当前代码中它只是分配相同的空数组[]。显然,如果返回一个承诺 - 这不是你所需要的。相反,您必须在控制器中 .then 它,并在那里分配值:

    GetFeed.getEpisodes().then(function(episodeArray){
       $scope.items = episodeArray;
    })
    

    【讨论】:

    • 非常感谢您的帮助。我修改了代码,并试图理解它。目前,随着您的更改,它仍然无法正常工作。更新代码以反映帖子的更改。
    • @tnotm,不要编辑原始问题 - 否则,问题和答案对其他人都没有意义。 (我恢复了更改)如果您需要进一步的帮助,请在 plunker 中复制问题
    • 这是你的分叉 plunker,删除了所有 xml 解析 - plnkr.co/edit/ssDph9gyHyQDQVVDbdbf?p=preview
    • 非常感谢。我仍然需要消化一些,但我想我明白了。我将在调用后修改数据并推送到控制器......或者可能在另一个服务中。我还将阅读异步和承诺。再次感谢。
    猜你喜欢
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 2014-06-03
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多