从模型中删除项目时,表单验证未更新。错误?

时间:2013-03-03 23:52:04

标签: javascript html validation angularjs

我最近开始使用AngularJS,我想我遇到了一个奇怪的错误。


首先,这是一些有效的代码:

查看:

<body ng-controller="MainCtrl">

    <form name="form">

        <div ng-repeat="phone in phoneNumbers">
            <input ng-model="phone.number" required />
            <button ng-click="deleteNumber($index)">Delete Number</button>
        </div>

        <button ng-click="addNumber()">Add Number</button>

        <input type="submit" ng-disabled="form.$invalid" />

    </form>

</body>

控制器:

app.controller('MainCtrl', function ( $scope ) {

    $scope.phoneNumbers = [{
        number: '212-123-4567'
    }];

    $scope.addNumber = function () {
        $scope.phoneNumbers.push({
            number: ''
        });
    };

    $scope.deleteNumber = function ( index ) {
        $scope.phoneNumbers.splice(index, 1);
    };

});

这是Plunkr:Working example

我认为代码非常简单:显示每个电话号码ng-repeat,您可以编辑/删除。如果添加了电话号码,则不能为空;如果有一个空电话号码,将禁用提交按钮。


当提交按钮位于ng-repeat上方时,会出现问题。如果您添加电话号码,将其留空,然后将其删除,则提交按钮将保持禁用状态:

<body ng-controller="MainCtrl">

    <form name="form">

        <input type="submit" ng-disabled="form.$invalid" />

        <div ng-repeat="phone in phoneNumbers">
            <input ng-model="phone.number" required />
            <button ng-click="deleteNumber($index)">Delete Number</button>
        </div>

        <button ng-click="addNumber()">Add Number</button>

    </form>

</body>

以下是plunkr:Broken example


我喜欢AngularJS,但这几乎让我疯狂。我花了20个小时追逐这个愚蠢的错误。由于通常的演示在底部有提交按钮,我无法重现该问题。我不得不采用我的实际代码,并慢慢将代码减少到最小。这是一个非常庞大而复杂的应用程序,而且......好吧,我现在不再抱怨了。

我的问题是双重的:

  1. 这是一个错误吗?我甚至尝试使用不稳定的分支(1.1.3),它的工作原理完全相同。

  2. 我可以做些什么来解决它,而不更改源订单。我知道我可以通过CSS移动我的提交按钮,但在我的情况下,这不是一个真正的选择;我需要提交按钮才能成为表格中的第一件事。


  3. P.S。 Here's a video of it in action

1 个答案:

答案 0 :(得分:5)

显然这是一个活跃的错误。

请参阅https://github.com/angular/angular.js/issues/1572

在该错误中,发布了一个使用隐藏计数器的变通方法,该计数器在添加/删除字段时递增 - 这用于强制Angular重新验证表单。

给出了一个例子jsFiddle:http://jsfiddle.net/HhcXT/

在模板中:

<input type="hidden" ng-bind="abc" />

在控制器中:

$scope.removeYears = function(item) {
    var index = $.inArray(item, $scope.years)
    $scope.years.splice(index, 1);        //remove element
    $scope.abc += 1;
}