ng-repeat不更新数组更新

Mis*_*cha 40 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>
Run Code Online (Sandbox Code Playgroud)

控制器(此功能在按钮上触发,点按ng键):

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

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

Ant*_*EVE 53

那是因为您在方法中更改了数组引用getDifferences.

为了避免这种情况,我们,例如使用"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>
    [...]
Run Code Online (Sandbox Code Playgroud)

如果你想了解范围是如何工作的,我会建议这篇文章: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
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑2:我的回答并不是很清楚,让我们试着深入了解正在发生的事情:

问: 为什么ng-repeat仍然有引用REFERENCE1?

您必须记住,模板中不仅有1个范围.

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

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

但原型继承存在一个问题:假设我们有A = {}; B = {C: 1},如果从那时A继承.但是,如果我们影响一个新的价值,我们只会改变.BA.C == 1A.C = 2BA

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

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

让我们回顾一下我们的例子:A = {}; B = {C: {D: 1}}如果从那时A继承.现在即使我们影响了一个新的价值,我们也改变了.BA.C.D == 1A.C.D = 2B


Osw*_*ldo 18

即使正确更新数组引用,我遇到了同样的问题,ng-repeat没有呈现我的更改.最后我通过调用$ scope找到了解决方案.$ apply();

$window.wizard.on("readySubmit", function () {
            var newArray = GenesisFactory.GetPermissionsFromTemplate(GenesisFactory.SecurityModules, true);
            $scope.NewSecurityProfileInstance.Permission.length = 0;
            newArray.forEach(function (entry) {
                $scope.NewSecurityProfileInstance.Permission.push(entry);
            });
            $scope.$apply();
        });
Run Code Online (Sandbox Code Playgroud)

我希望这可以提供帮助.

  • $范围$适用().为我工作谢谢#Oswaldo (2认同)

sh6*_*210 5

我什么也没做,但是在推送元素之后添加了这行“ $ scope。$ apply() ”,我完成了。