一尘不染

ng-repeat不更新数组更新

angularjs

我正在通过ng-repeat循环渲染数据。而且我希望它在更新数组时进行更新。从我阅读的内容来看,这应该会自动发生,但是这是行不通的。那我在做什么错?

的HTML:

<tr ng-repeat="data in dataDifferenceArray">
    <td>
      {{data.name}}
    </td>
    <td>
      {{data.startData}}
    </td>
    <td>
      {{data.endData}}
    </td>
    <td>
      {{data.differenceData}}
    </td>
</tr>

控制器(此功能通过ng-click在按钮上触发):

$scope.getDifferences = function () {
  $scope.dataDifferenceArray = [];
  var i;
  for (i = 0; i < 20 ;i++) {
    $scope.dataDifferenceArray.push({
      name : 30,
      startData : 20,
      endData : 2,
      differenceData : 30
    })
  }
}

Console.log显示该数组已正确更新,但是我视图中的表未更改。我不知道我在做什么错。


阅读 277

收藏
2020-07-04

共1个答案

一尘不染

那是因为您在method中更改了数组引用getDifferences

为了避免这种情况,我们使用 dot ,例如使用“ controller as”语法:

<div ng-controller="myController as c">
    [...]

    <tr ng-repeat="data in c.dataDifferenceArray">
        <td>
          {{data.name}}
        </td>
        <td>
          {{data.startData}}
        </td>
        <td>
          {{data.endData}}
        </td>
        <td>
          {{data.differenceData}}
        </td>
    </tr>
    [...]

如果您想了解范围是如何工作的,我会建议这篇文章:https : //github.com/angular/angular.js/wiki/Understanding-
Scopes#ngRepeat

另一个解决方案可能是:

$scope.getDifferences = function () {
  $scope.dataDifferenceArray.length = 0; // here ----
  var i;
  for (i = 0; i < 20 ;i++) {
    $scope.dataDifferenceArray.push({
      name : 30,
      startData : 20,
      endData : 2,
      differenceData : 30
    })
  }
}

但是在此解决方案中,您需要在外部创建数组(并且仅创建一次): $scope.dataDifferenceArray = [];

Edit2: 我的答案不是很清楚,让我们尝试深入了解正在发生的事情:

问: 为什么ng-repeat仍然有参考REFERENCE1?

您必须记住, 模板中不仅只有1个作用域

例如:ng-repeat指令为每个重复的元素创建新的作用域,但是我们仍然可以访问每个子作用域中的父作用域。Angular使用 Prototype
Inheritance
实现了此行为:由于其原型,每个子范围都继承了其父范围的属性。

您可以通过检查子元素上的元素来进行实验,然后在控制台中输入:($($0).scope()它将为您提供选定元素的范围,$0即选定元素(Chrome))。您现在可以看到,在相同的对象$($0).scope().$parent$($0).scope().__proto__,这是你的父母范围。

但是原型继承有一个问题:假设我们有继承,那A = {}; B = {C: 1}就是A继承。但是,如果我们影响一个新的价值,我们没有改变而已,。B``A.C == 1``A.C = 2``B``A

使用当前范围作为评估角表达式this。因此,如果我们有像ng-click="dataDifferenceArray = []"它相当于this.dataDifferenceArray = []this是其中所述元素的范围ng-click是。

当您使用 controller-as 时,此问题已解决 因为它将控制器注入到合并范围中,并且您将永远不会直接影响合并范围的属性。

让我们回顾一下示例:A = {}; B = {C: {D: 1}}如果A继承自Bthen A.C.D == 1。现在,即使我们影响了新的价值A.C.D = 2,我们B也改变了。

2020-07-04