【问题标题】:AngularJS ng-repeat refresh with new API callAngularJS ng-repeat 使用新的 API 调用刷新
【发布时间】:2018-12-09 01:00:12
【问题描述】:

目前正在开发一个应用程序,我正在执行 API 调用以获取数据,然后使用 ng-repeat 指令填充视图上的表格。

<tr md-row ng-repeat="request in requests">
        <td md-cell>{{request.name}}</td>
        <td md-cell>{{request.email}}</td>
        <td md-cell>{{request.application_name}}</td>
        <td md-cell>{{request.created_user}}</td>
        <td md-cell>{{request.request_type}}</td>
        <td md-cell>{{request.status}}</td>
</tr>

在控制器中,用户发出一个新请求并向数据库添加一行,在成功对话框出现后,我想向 API 发出一个新请求以获取服务器生成的新行,所以我想提出一个新的 API 请求。

所以,我联系 API 并再次获取所有请求,并希望将表上的数据替换为来自 API 的刷新数据

当 API 调用成功时,它会从 promise 中调用这个函数:

var onRequests = function(response) {
  $scope.requests = [];

      response.forEach(function() {
          //Processing here and pushing to the new array
      });
  });
};

但是,在创建这个新数组时,我假设 ng-repeat 片段的作用域对原始数组的引用丢失了。

所以,我正在尝试找到一种方法来使用新数组刷新 ng-repeat 表。

以下是我尝试过的事情:

  • 新建数组,然后$applying

  • 保持相同的数组引用并删除所有内容并执行 再一次,但这似乎是一种 hacky 方式,我想要一个优雅的 解决方案

  • 使用 $rootScope 代替数组,这似乎对某些人有用 原因……

这就是我做 $rootScope 的方法,它有效(但看起来很老套):

 var onRequests = function(response) {
      $rootScope.requests = [];

          response.forEach(function() {
              //Processing here and pushing to the new array
          });
      });
    };

出于某种原因这行得通,我不知道为什么会这样。这就是为什么我不明白。

问题:当我调用 api 时,会调用此函数并将 $scope.requests 设置为空数组(这会更改地址/丢失引用吗?),然后填充使用来自 API 的新数据。我想知道 这是否不会用新数据更新 ng-repeat 子范围

我知道,通常如果您更改 ng-repeat $scope 数组,它应该更新 DOM,但由于我将它设置为一个空的新数组,然后填充该新数组,它似乎正在丢失对数组的引用。 这就是为什么如果我去弹出数组上的每个元素而不是仅仅将它设置为一个全新的空数组(例如$scope.requests = [];


我想要什么

不管这是否是解决问题的最佳方法。我想要做的就是用来自 API 调用的新数据更新 ng-repeat 表。

如果有人可以帮助我,那就太棒了。我已经阅读了其他类似的问题,但似乎找不到任何有用的或与我正在尝试做的事情完全相同的东西,从我发现的情况来看,它没有用。

编辑:为了清楚起见,我已经阅读了大约十几个其他措辞相似的帖子,没有一个与我所说的那样完全一致,所以在标记为之前重复,知道很多其他的都不能作为解决方案。

【问题讨论】:

  • 尝试将 forEach 置于 超时 内,即 0 秒的 setTimeout$timeout,以便在下一个摘要周期中进行更改。
  • @SatishKumar,刚试过,没用:(
  • 检查这个Plunker,这个想法和你的问题一样。只需使用$timeout
  • 我不确定我是否理解您的问题。如果您想用新数据替换以前的数据,您的两个示例都应该有效。您是否需要保留对旧数据的引用?如果有,为什么?
  • 不清楚为什么 DOM 没有更新。一种可能是调用 API 的方法没有与 AngularJS 框架集成。作为 AngularJS 框架一部分的 $http 服务在使用对 ng-repeat 的新引用进行更新时没有问题。

标签: javascript angularjs web


【解决方案1】:

听起来这是你的问题:

所以,我试图找到一种方法来刷新 ng-repeat 表 使用新数组。

简短的回答是这样的:

$scope.requests = newArrayOfRequests;

或者,你所拥有的也可以:

//clear the array. I don't why you would need a reference to the old array,
// but if you do, then
//$scope.old = requests;
//then
$scope.requests = [];

response.forEach(function() {
  // do your processing
  $scope.requests.push(processedRow)
});

就是这样。在 AngularJS 中,这就是你所要做的。这就是 AJS 绑定的魔力。

现在,您可以通过将track byng-repeat 结合使用来改进一些性能。但是,这就是您刷新 ng-repeat 所要做的全部工作。

更长的答案与 DOM 节点有关。 AJS 确实使用它创建的通用 ID 跟踪添加到 ngRepeat 的每件事(如果您在开发工具中检查表,您实际上可以将这些 ID 视为属性)。但是,除非可以将这些 ID 映射回您的数据,否则这对您没有帮助。幸运的是,您可以使用 track by 指定它使用来自实际数据的唯一 ID:

<tr md-row ng-repeat="request in requests track by request.some_unique_id">
        <td md-cell>{{request.name}}</td>
        <td md-cell>{{request.email}}</td>
        <td md-cell>{{request.application_name}}</td>
        <td md-cell>{{request.created_user}}</td>
        <td md-cell>{{request.request_type}}</td>
        <td md-cell>{{request.status}}</td>
</tr>

这样做的目的是允许 AJS 重新使用它之前在第一次加载数据时创建的 DOM 节点,而不是在每次加载新数据时重新创建它们。

当您加载新数组时,AJS 只需更新每一行的值,或者在您的情况下,它只需为 API 返回的新行添加一个 DOM 节点

但这不会改变数据的刷新方式。只需将新数组分配给$scope 变量,或清除它并推送新数据。仅此而已。

【讨论】:

  • 这正是我想要做的,是的!但是,由于某种原因,当我将这个新数组加载到 ng-repeat 使用的 $scope 数组中时,它不会更新 DOM。我在想也许 ng-repeat 创建的子范围没有对新数组的引用,因为新数组只是由 $scope.requests = [] 创建然后填充它?当我按照您的建议进行操作时,它似乎没有更新 Dom,但确实正确更新了数组。感谢您的深入回复!你认为什么是正确的格式化方式?
  • 另外,为了清楚起见,我不需要对旧数组的引用,如果我遇到这样的情况很抱歉。我实际上只是希望表使用新的 API 调用重新填充数据,但是当我设置 $scope.requests = []; 时,我担心在 ng-repeat 行上创建的范围会丢失引用,因为现在 $scope.requests 指向新数组而不是填充表格的那个。这就是为什么如果我从数组中弹出每个元素而不是将其设置为等于一个全新数组的原因。那么,话虽如此,解决问题的好方法是什么?
  • 好的,有道理。如果您没有看到表中的数据更新,那么您可能遇到了我们无法从您的代码中看到的更深层次的问题。@georgeawg 是对的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多