AngularJS 使用控制器中的函数从服务中返回数据以用于 ng-repeat

Posted

技术标签:

【中文标题】AngularJS 使用控制器中的函数从服务中返回数据以用于 ng-repeat【英文标题】:AngularJS use a function in a controller to return data from a service to be used in ng-repeat 【发布时间】:2014-01-23 10:31:26 【问题描述】:

我正在尝试使用控制器中的函数来返回数据,以便我可以在整个应用程序中重复使用该函数来调用数据以及偶尔刷新它。

我的代码看起来是正确的,但实际上,每次加载时浏览器都会崩溃。

我可以通过使用 E 指令然后将元素放置在部分中来使其工作,但这并不能满足我的需要。

最终,我想做这样的事情:

<div ng-repeat="user in getListUsers()"> user.somedata </div>

我尝试了各种方法让它在测试中工作,包括将 $http 放入控制器中,所有结果都相同。

如果我在控制器方法中分配一个变量而不是返回数据,那是可行的,但是我需要在控制器中调用该方法,并且我不希望它默认运行。只是希望在需要时在模板中进行调用。

任何帮助弄清楚为什么这不起作用会很棒。谢谢。

这是我所拥有的不起作用的东西......

elite.controller('UserController', function($scope, User)

    $scope.getListUsers = function()
        User.listUsers().then(function(response)
            return response.users;
        );
    

);

elite.factory('User', function($http)
   var User = 
      getUser: function(id)
          return $http.get('/user/' + id + '/settings').then(function(response)
              return response.data; 
          );
      ,
      listUsers: function()
        return $http.get('/user/').then(function(response)
          return response.data;
        );
      
   
   return User;
);

编辑:

使用下面的一些想法,我能够以不同的方式获得我想要的功能。基本上,我希望数据按需加载,而不是预先加载,因为我试图在该控制器中对所有用户逻辑进行分组,并且我不希望为每个用户加载完整数据。我暂时使用 $rootScope 直到我找出一些范围继承问题,因为使用 $scope.users 最终在模板中得到一个空值。我可以看到 AJAX 调用回来了,但不确定它的去向,但这是另一个问题。

elite.controller('UserController', function($scope, $rootScope, User)

    $scope.getListUsers = function()

        User.listUsers().then(function(response)
            $rootScope.users = response.users;
        );
    ;

);

在导航元素中我有这个:

<div ng-controller="UserController">
<a ng-href="/#user/list" ng-click="getListUsers()">user list</a>
</div>

【问题讨论】:

查看***.com/questions/12336897/… 我之前看到过,但即使我不使用 ng-repeat 也会出现问题。例如,如果我只是将函数放在括号中,例如 getListUsers() ,浏览器仍然会崩溃而不是显示对象。 【参考方案1】:

这是关于 $digest、$watch 和 ng-repeat 的。您可以通过简单的谷歌搜索或查看 Jsplaine 提供的链接找到很多答案。

简而言之,您的 getListUsers() 函数在每次调用时都会返回一个用户列表。但是,每个返回的列表都是一个新集合(数组)。对于角度来说,这意味着它必须更新页面上列表的显示。每次更新后,Angular 实际上会通过再次调用 getListUsers() 函数来检查几次列表是否稳定。每次angular发现列表不一样,就不断更新列表,不断调用getListUser函数。

为了解决这个问题,你可以创建一个保存用户列表的变量:

 $scope.userList = [];

还有更新列表的功能

$scope.reloadListUsers = function()
    User.listUsers().then(function(response)
        $scope.userList = response.users;
    );

然后在 ng-repeat 指令中

<div ng-repeat="user in userList"> user.somedata </div>

你想在哪里重新加载列表,只需调用 reloadListUsers 函数即可。

<button ng-click="reloadListUsers()" > reload </button>

背后的原因是现在绑定中使用了变量userList而不是函数调用表达式,并且一旦加载列表就变得稳定了。

【讨论】:

我想我明白你在说什么,Angular 并没有像我想象的那样工作。我觉得我已经看到了其他将函数用作对象的代码,但我可能是错的。我已经使用您建议的一些内容编辑了上面的问题,现在我遇到了范围问题,但我可能会解决这个问题。【参考方案2】:

有一些问题。您正在从一个匿名函数返回一个值,该函数在 $http.get 调用返回的承诺被解析时被调用。该函数的返回值不会是从 getListUsers 返回的值。

另外,您在控制器回调中引用了 response.users。那仍然是原始响应对象。您可能打算引用 response.data.users?

试试这个:

elite.controller('UserController', function($scope, User)

$scope.users = [];

$scope.getListUsers = function()
    User.listUsers().then(function(response)
        $scope.users = response.data.users;
    );

);

elite.factory('User', function($http)
 var User = 
  getUser: function(id)
      return $http.get('/user/' + id + '/settings');
  ,
  listUsers: function()
    return $http.get('/user/');
   

  return User;
);

然后,在视图中绑定它:

<div ng-repeat="user in users"> user.somedata </div>

如果用户未定义或为空,ng-repeat 指令不会吐出任何元素。

【讨论】:

它与 response.users 一起工作,原始数据在服务中得到处理。

以上是关于AngularJS 使用控制器中的函数从服务中返回数据以用于 ng-repeat的主要内容,如果未能解决你的问题,请参考以下文章

如何让控制器等待服务返回值以及如何访问控制器中的返回值?

AngularJS:从字符串中插入 HTML

AngularJS 错误:fnPtr 不是函数

如何从AngularJS中的另一个控制器调用函数? [复制]

在AngularJs中从控制器调用服务时,从$ get factory方法返回一个值

AngularJS 从控制器触发并观察服务中的对象值变化