9

我正在尝试将对象从函数返回到 ng-repeat:

<ul ng-controller="Users" ng-repeat="user in users">
    <li ng-controller="Albums" ng-repeat="album in getAlbumList(user.name)">
        {{album.title}}
    </li>
</ul>

.controller('Albums', ['$scope','Imgur', function($scope, Imgur) {
    $scope.getAlbumList = function(user) {
        Imgur.albumList.get({user:user},    
            function(value) {
                return value.data;
                console.log('success');
            },
            function(error) {
                console.log('something went wrong');
            }
        );
    }
}]);

.factory('Imgur', function($resource, $http) {
    return {
        albumList : $resource('https://api.imgur.com/3/account/:user/albums'),
        album : $resource('https://api.imgur.com/3/account/:user/album/:id')
    }
});

然而,这种方法在每次页面加载时都会使我的浏览器崩溃。

这样做的正确方法是什么?

4

2 回答 2

12

所以,你有ng-repeat="album in getAlbumList(user.name)",这是一个 Angular 表达式。ng-repeat 所做的是评估getAlbumList(user.name)每个摘要。这就像视图中的任何其他表达式一样,例如 ng-show 或其他任何表达式,并且这些表达式一直被评估。如果您的表达式计算数百次的速度很慢,那么您不应该在这样的表达式中使用它。

您在这里拥有的是该函数中的 Ajax 调用。即使您以某种方式有一个阻塞的同步 Ajax 调用,它也会太慢几个数量级。表达式应该只访问手头的数据,或者运行简单的代码来排序和过滤。他们不应该尝试进行 Ajax 调用。

但这是假设它是同步的 Ajax,而事实并非如此。该表达式只是调用getAlbumList并假设结果是一个数组并将其用于 ng-repeat。该函数什么也不返回,所以它返回undefined,你什么也得不到。

所以要回答你的问题,你应该做的是,在作用域上放置一个空数组,从 ng-repeat 中使用它,然后通过 Ajax 填充它。Angular 的美妙之处在于,数据一旦出现,就会在视图中“弹出”。这是一些视图代码:

<ul>
  <li ng-repeat="album in albums">{{album.title}}</li>
</ul>

还有一些控制器代码:

$scope.albums = [];
Imgur.albumList.get({user:user},
    function(value) {
        $scope.albums = value.data;
        console.log('success');
    },
    function(error) {
        console.log('something went wrong');
    }
);

这基本上是您已经拥有的代码,只是不是从函数中运行,而是在控制器的构造函数中运行。

编辑

我认为您的基本误解是认为从 ngResource 回调返回的内容又会从包含函数(getAlbumList)返回。事实并非如此。包含函数运行,什么也不返回,然后在你的回调运行后,返回一些东西,但没有人使用那个返回值。

于 2013-05-08T04:44:05.760 回答
6
<ul ng-controller="Users">
     <li ng-repeat="user in users">
       <ul ng-controller="Albums" ng-init="getAlbumList(user.name)">
          <li ng-repeat="album in albums">
           {{album.title}}
          </li>
       </ul>
     <li>
</ul>


.controller('Albums', ['$scope','Imgur', function($scope, Imgur) {
    $scope.getAlbumList = function(user) {
        Imgur.albumList.get({user:user},    
          function(value) {
                $scope.albums = value.data;
                console.log('success');
          },
          function(error) {
              console.log('something went wrong');
          }
      );
    }}]);

试试这个。如果没有,那么检查这个问题 Reusable components in AngularJS

于 2013-05-07T02:30:06.467 回答