42

これが私の問題のデモです。

$scope.myNumbers = [10, 20, 30];

<div ng-repeat="num in myNumbers">
    <input type="text" ng-model="num">
    <div>current scope: {{num}}</div>
</div>

入力が編集不可/読み取り専用である理由を誰かが私に説明できますか?それが設計によるものである場合、背後にある理論的根拠は何ですか?

2014年2月20日更新

これはv1.2.0以降のデモでは問題ではなくなったようです。ただし、ユーザーコントロールは新しいangularJSバージョンで編集可能になりましたが、変更されるのは親スコープではなく子スコープnumのプロパティであることに注意してください。つまり、ユーザーコントロールの値を変更しても、配列には影響しません。myNumbers

4

5 に答える 5

67

入力が編集不可/読み取り専用である理由を誰かに説明できますか? 設計によるものである場合、その背後にある理論的根拠は何ですか?

Angular 1.0.3 の時点で、これは設計によるものです。Artem は、「各 ng-repeat アイテムに直接バインドする」場合に 1.0.3+ がどのように機能するかについて非常に適切に説明しています。つまり、

<div ng-repeat="num in myNumbers">
  <input type="text" ng-model="num">

ページが最初にレンダリングされるときのスコープの図を次に示します (配列要素の 1 つを削除したため、図のボックスが少なくなります)。

ここに画像の説明を入力 (拡大するにはクリックしてください)

破線は、プロトタイプのスコープ継承を示しています。
灰色の線は、子→親の関係 (つまり、何を$parent参照しているか) を示しています。
茶色の線は $$nextSibling を示しています。
灰色のボックスはプリミティブ値です。青いボックスは配列です。紫はオブジェクトです。

あなたがコメントで参照したSOの答えは、1.0.3が出る前に書かれたことに注意してください。1.0.3 より前ではnum、テキスト ボックスに入力すると、ngRepeat 子スコープの値が実際に変更されていました。(これらの値は親スコープでは表示されません。) 1.0.3 以降、ngRepeatはダイジェスト サイクル中にnumngRepeat スコープの値を親/MainCtrl スコープの配列からの (変更されていない) 値に置き換えるようになりました。myNumbersこれにより、基本的に入力が編集できなくなります。

修正は、MainCtrl でオブジェクトの配列を使用することです。

$scope.myNumbers = [ {value: 10}, {value: 20} ];

value次に、ngRepeat でオブジェクトのプロパティにバインドします。

<div ng-repeat="num in myNumbers">
  <input type="text" ng-model="num.value">
  <div>current scope: {{num.value}}</div>
于 2013-03-19T03:21:10.330 に答える
34

この問題は現在、AngularJS の最近のバージョンで対処されており、track byプリミティブを介したリピーターを許可する機能があります。

<div ng-repeat="num in myNumbers track by $index">
  <input type="text" ng-model="myNumbers[$index]">
</div>

キーストロークごとにページが再描画されないため、フォーカスが失われる問題が解決されます。公式の AngularJS doc は、これについて非常に曖昧で混乱しています。

于 2014-02-19T16:28:31.160 に答える
9

同様の問題があり(「追加」および「削除」機能も必要でした)、次のように問題を解決しました。

$scope.topics = [''];
$scope.removeTopic = function(i) {
   $scope.topics.splice(i, 1); 
}

<div ng-repeat="s in topics track by $index">
    <input ng-model="$parent.topics[$index]" type="text">
    <a ng-click="removeTopic($index)">Remove</a>
</div>

<a ng-click="topics.push('new topic')">Add</a>
于 2013-12-18T05:23:02.723 に答える
9

Angular は、そのように定義されたモデルに書き込むことができないようです。最初の $scope 属性への参照を使用して、値を正しい方法でバインドできるようにします。

<div ng-repeat="num in myNumbers">
  <input type="text" ng-model="myNumbers[$index]">
</div>
于 2013-03-18T22:54:33.983 に答える
9

ngRepeat はソース配列への参照を使用します。integer (Number in js)参照型ではなく型であるため、javascript で参照渡しすることはできません。変更は反映されません。

ここにデモンストレーションがあります:

   var x = 10;
   var ox = {value:10};

   var y = x;
   var oy = ox;

   y = 15
   oy.value = 15;

xとの値は何でしょうoxか?

>> x = 10;
>> y = 15;
>> ox = {value:15};
>> oy = {value:15};

すべての JavaScript オブジェクトは参照によって渡され、すべてのプリミティブは値 ["string"、"number" など] によって渡されます。

働くプランカーhttp://plnkr.co/edit/7uG2IvAdC2sAEHbdHG58

于 2013-03-18T23:06:16.693 に答える