ng-repeat 中的 ng-init 何时重播?

When ng-init in ng-repeat is replays?

我有一个简单的 ng-repeat 从 javascript 数组构建 HTML 列表。 可以使用输入来移动每个项目以获得新的排名。此输入绑定到变量 rank。此变量使用 ng-init 指令初始化。

代码如下所示:

<li ng-repeat="item in ctrl.getItems()">
  <div ng-init="rank = $index">
    [$index: {{$index}}]
    {{item}}<br/>
    <label>
      Move to
      <input type="number" ng-model="rank"/>
    </label>
    <button type="button" ng-click="ctrl.moveItem($index, rank)">
      Ok
    </button>
  </div>
</li>

在运行时,当我更改输入值并单击“确定”按钮时,函数 ctrl.moveItem 被调用,项目真正移动到 ctrl.getItems() 数组中。

所以 ng-repeat 被重播并且项目出现在新的顺序中。

BUT 变量 rank 未重新初始化,并且出现了 2 个具有相同等级的项目。

样本在这里:https://jsfiddle.net/nlips/4ng34b7b/

我的问题不是关于移动列表中的项目,而是我需要了解 ng-init 如何在 ng-repeat 的上下文中工作。

我在 AngularJS 官方文档中没有找到关于这个主题的任何内容。

来自 AngularJS 文档:

The ngInit directive allows you to evaluate an expression in the current scope.

现在。您正在使用不同的范围。

您正在使用 ngInit 进入 嵌入范围 ,覆盖 $scope.rank 每次重复模板的那部分。

如果你想保持你的排名,你应该将它初始化到 ngRepeat 范围

试试:

<li ng-repeat="item in ctrl.getItems()" ng-init="rank = $index">
  [$index: {{$index}}]
  {{item}}<br/>
  <label>
    Move to
    <input type="number" ng-model="rank"/>
  </label>
  <button type="button" ng-click="ctrl.moveItem($index, rank)">
    Ok
  </button>
</li>

已编辑答案

好的,我知道了。 ngInit 表达式仅在模板的该部分将被渲染到 DOM.

时才被评估

因此,当页面第一次加载时,您的表达式会被触发,并且每个 rank 都会被正确评估。

但是,当您对已经呈现的项目进行更改时,您的模板不会再次呈现,因此您的 ng-init 不会被触发。

如果您希望再次执行 ng-init,您必须 从 DOM 中删除 项目并且然后将其追加到新位置。

这种方法有几种替代方法,但我希望这能澄清发生了什么。