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 中删除 项目并且然后将其追加到新位置。
这种方法有几种替代方法,但我希望这能澄清发生了什么。
我有一个简单的 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 中删除 项目并且然后将其追加到新位置。
这种方法有几种替代方法,但我希望这能澄清发生了什么。