AngularJS: ng-if 在 ng-repeat 之外中断 ng-repeat

AngularJS: ng-if outside ng-repeat breaks ng-repeat

AngularJS 版本: 1.3.8

JSFiddle: http://jsfiddle.net/uYFE9/4/

我一直在开发一个小型 AngularJS 应用程序,运行 遇到了一些问题。我在一个页面上有一个 ng-repeat ,它填写了一个表格的内容。表单中的项目数量由绑定到模型的下拉列表定义,并使用 ng-options 填充。类似于:

<select id="testAmount" ng-model="selectedItem" ng-options="item.name for item in items"></select>

<form role="form" name="testForm" ng-if="!complete">
    <div ng-repeat="i in getNumber(selectedItem.number) track by $index">
        {{$index}}
    </div>
</form>

Complete 一开始设置为 false,点击 Next 按钮将切换 complete 并隐藏表单和下拉菜单。然后 Back 按钮将 complete 切换回来,并再次显示表单。

我遇到的问题是 select 上的 ng-if(之前,我将表格包裹在 div 中,同样 ng-if - 同样的问题)。当 select 下拉列表更改时,ng-repeat 不再更新。删除 select 上的 ng-if 会将 ng-repeat 恢复到工作状态。

我想知道这里的嵌套是否有问题运行ge,或者它是否真的是一个错误?您可以在上面链接的 JSFiddle 上对其进行测试。 $index 应该在下拉列表中打印次数,但不是。

有趣的是 - 在我的本地机器上调试问题时,打开 FireBug 解决了问题。

ng-if 给您带来了一些范围界定问题(这会扰乱绑定)。

这里有一个 updated jsfiddle,您可以将其用作变通方法。本质上,此示例将另一个 div 包裹在您希望最终隐藏的项目周围。然后添加一个 next 功能,以便在将 complete 设置为 true.

的点击期间影响相同的范围

HTML:

<div ng-app="test">
    <div ng-controller="TestCtrl">
        <div ng-if="!complete">
            <div>
                <label for="testAmount">Amount:</label>
                <select id="testAmount" ng-model="selectedItem" ng-options="item.name for item in items"></select>
            </div>

            <form role="form" name="testForm">
                <div ng-repeat="i in getNumber(selectedItem.number) track by $index">
                    {{$index + 'hi'}}
                </div>
                <button class="btn btn-default" value="Next" title="Next" ng-click="next()">Next</button>
            </form>
        </div>

        <div ng-if="complete">

        </div>
    </div>
</div>

JS:

angular.module('test', [])
.controller('TestCtrl', function($scope) {
    $scope.complete = false;

    $scope.items = [
        { name: '2', number: 2 },
        { name: '3', number: 3 },
        { name: '4', number: 4 }
    ];

    $scope.selectedItem = $scope.items[0];

    $scope.getNumber = function (number) {
        return new Array(number);
    };

    $scope.next = function() {
      $scope.complete = true;  
    };
})

这是因为 ng-if 创建子作用域以及原型继承如何与基元一起工作。在这种情况下,原语是 selectedItem,您由 <select> 设置,但实际上是在子范围和 shadows/hides 父范围 属性 上设置的。

一般来说,您应该始终在 ng-models:

中使用点 (.)
$scope.selection = {selectedItem: undefined};

在视图中:

<div ng-if="!complete">
  <select ng-model="selection.selectedItem" 
          ng-options="item.name for item in items"></select>
</div>

我认为问题出在 ng 中的 select 语句 - 如果 selectedItem 从未设置。如果您只是不想在 !complete 时显示该下拉菜单,请将其更改为 ng-show 并且它可以正常工作。

    <div ng-show="!complete">

至于为什么 ng-model 没有被绑定在 ng-if 中,我真的不知道,但它确实有一定道理,因为你正在尝试做一个有点古怪的条件绑定