8

最近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 時間以上費やしました。通常のデモでは送信ボタンが下にあるため、問題を再現できませんでした。実際のコードを取得し、ゆっくりとコードを最小限に抑える必要がありました。これは非常に大規模で複雑なアプリです。

私の質問は 2 つあります。

  1. これはバグですか?不安定なブランチ (1.1.3) でもこれを試してみましたが、まったく同じように動作します。

  2. source order を変更せずに回避するにはどうすればよいですか。CSS を介して送信ボタンを移動できることはわかっていますが、私の場合、それは実際にはオプションではありません。送信ボタンをフォームの最初にする必要があります。


PSこれが動作中のビデオです

4

1 に答える 1

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;
}
于 2013-03-04T00:36:43.517 に答える