【问题标题】:AngularJS $http don't trigger digest loopAngularJS $http 不会触发摘要循环
【发布时间】:2016-05-20 23:36:06
【问题描述】:

我有角度摘要循环的问题。当我进行 http 调用并将响应放入 $scope 时,该 var 在下一个摘要循环之前不会在视图中更新。

例如我将以下调用包装到视图上的函数和按钮中,该视图使用 ng-click 调用函数。当我第一次单击按钮时,视图上什么都没有发生(发送了 http 响应并收到了响应)。第二次单击按钮后,视图会使用先前响应的数据更新,当前响应会在下一次单击后更新等...

$scope.loadItems = function(){
   ItemService.getData().then(function(rsp) {
      $scope.items = rsp.data;
    });
}

ItemService.getData() 基本上是在包装 $http 调用:

getData : function(){
    return $http({
    method: 'GET',
    url: '/api/items'
    });
}

还有html

<button ng-click="loadItems()">Load</button>

谢谢!

【问题讨论】:

  • 我们能看到 ItemService.getData() 的代码吗?此外,从 ng-click 调用的整个函数代码。
  • 很高兴看到更多。也许发布您使用的控制器和相应的 HTML 部分。
  • 我更新了 html 和服务的信息
  • @DušanStanković,您找到解决问题的方法了吗?如果是的话,你能和我们分享一下吗?我对问题所在非常感兴趣,它也可能对其他用户有所帮助。
  • 问题是 $http 被错误注入并且它没有触发它自己的摘要循环。

标签: angularjs http angularjs-digest


【解决方案1】:

好的,我想问题如下。我打赌你会在 ng-repeat 中使用 $scope.items,对吗?例如

<ul>
    <li ng-repeat="item in items">
        //Here goes my little item
    </li>
</ul>

对吗?嗯,有一个问题。 ng-repeat 引用“items”集合,一旦引用的集合发生更改,HTML 就会更新。但是...做的问题

$scope.items = rsp.data;

是您为“项目”分配了一个全新的集合,该集合未被 ng-repeat 引用 - 它仍然引用未更改的旧集合。因此,以下应该有效 - 在您的 $scope 中使用一个点。

控制器:

$scope.data = {};

ItemService.getData().then(function(rsp) {
    $scope.data.items = rsp.data;
});

查看:

<ul>
    <li ng-repeat="item in data.items">
        //Here goes my little item
    </li>
</ul>

换句话说,问题不在于调用摘要循环——它被调用了。问题在于滥用 $scope。

This link 应该会有所帮助。它更详细地解释了范围的细微差别。

【讨论】:

  • 这在全球范围内发生,在每一个 http 请求上,所以我应该在我拥有的每一个 http 请求上都这样做。还有其他解决方案吗?附言它也可以在 $timout 中使用
  • 您可以观看 $scope.items。
  • @DušanStanković,请查看我的更新答案。我想我一开始回答得有点着急......
  • 另外,这已经完成了,我猜这与http有关,知道为什么要在scope.apply之外完成吗?
  • 不知道,对不起。我看不出为什么会在适用范围之外调用它。
【解决方案2】:

您需要将 getData() 更改为如下所示:

getData: function() {
  return $http({
  method: 'GET',
  url: '/api/items'
  }).then(function(response) {
    return response.data;
  }, function(error) {
    return error;
  });
}

和 $scope.loadItems() 到

$scope.loadItems = function(){
   ItemService.getData().then(function(rsp) {
      $scope.items = rsp;
    });
}

【讨论】:

  • 不,这不是必须的,他可以返回promise并在调用服务方法的客户端代码中调用“then”方法——就像他所做的那样。
猜你喜欢
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多