ngRepeat
とngModel
を使用して、ユーザーがアイテムのリストを編集できるようにしようとしています。 ( このフィドルを参照 。)しかし、私が試みた両方のアプローチは奇妙な振る舞いにつながりました:1つはモデルを更新せず、もう1つは各キーダウンでフォームをぼかします。
ここで何か間違ったことをしていますか?これはサポートされているユースケースではありませんか?
便宜上、コピーされたフィドルのコードを次に示します。
<html ng-app>
<head>
<link href="//netdna.bootstrapcdn.com/Twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body ng-init="names = ['Sam', 'Harry', 'Sally']">
<h1>Fun with Fields and ngModel</h1>
<p>names: {{names}}</p>
<h3>Binding to each element directly:</h3>
<div ng-repeat="name in names">
Value: {{name}}
<input ng-model="name">
</div>
<p class="muted">The binding does not appear to be working: the value in the model is not changed.</p>
<h3>Indexing into the array:</h3>
<div ng-repeat="name in names">
Value: {{names[$index]}}
<input ng-model="names[$index]">
</div>
<p class="muted">Type one character, and the input field loses focus. However, the binding appears to be working correctly.</p>
</body>
</html>
これは拘束力のある問題のようです。
アドバイスは プリミティブにバインドしない です。
ngRepeat
は、コレクション内の文字列を繰り返し処理しています(オブジェクトを繰り返し処理する必要がある場合)。問題を解決するには
<body ng-init="models = [{name:'Sam'},{name:'Harry'},{name:'Sally'}]">
<h1>Fun with Fields and ngModel</h1>
<p>names: {{models}}</p>
<h3>Binding to each element directly:</h3>
<div ng-repeat="model in models">
Value: {{model.name}}
<input ng-model="model.name">
</div>
jsfiddle: http://jsfiddle.net/jaimem/rnw3u/5/
Angular最新バージョン(1.2.1)を使用し、$index
で追跡します。この問題は修正されました
<div ng-repeat="(i, name) in names track by $index">
Value: {{name}}
<input ng-model="names[i]">
</div>
scopes 、 ngRepeat および ngModel with NgModelController の仕組みを理解する必要がある場合、困難な状況に陥ります。また、1.0.3バージョンを使用してみてください。あなたの例は少し異なる動作をします。
Jm-が提供するソリューションを簡単に使用できます。
しかし、状況をより深く処理したい場合は、理解する必要があります。
AngularJS 1.0.3の例「各要素への直接バインド」の仕組み:
'f'
を入力します。ngModelController
は項目スコープのモデルを変更します(names配列は変更されません)=> name == 'Samf'
、names == ['Sam', 'Harry', 'Sally']
;$digest
ループが開始されます。ngRepeat
は、項目スコープ('Samf'
)からのモデル値を、変更されていない名前配列('Sam'
)からの値で置き換えます。ngModelController
は、実際のモデル値('Sam'
)で入力を再レンダリングします。「配列へのインデックス付け」の例の仕組み:
'f'
を入力します。ngModelController
は名前の項目を変更しますarray
=> `names == ['Samf'、 'Harry'、 'Sally'];ngRepeat
はキャッシュで'Samf'
を見つけることができません。ngRepeat
は新しいスコープを作成し、新しい入力を持つ新しいdiv要素を追加します(そのため入力フィールドがフォーカスを失います-古い入力を持つ古いdivは新しい入力を持つ新しいdivに置き換えられます)。また、 AngularJS Batarang を使用して、入力した入力でdivのスコープの$ idがどのように変化するかを確認することもできます。
キーストロークごとにモデルを更新する必要がない場合は、name
にバインドしてからblurイベントで配列項目を更新するだけです:
<div ng-repeat="name in names">
Value: {{name}}
<input ng-model="name" ng-blur="names[$index] = name" />
</div>
AngularJsを1.1.2に更新したところ、問題ありません。このバグは修正されたと思います。
http://ci.angularjs.org/job/angular.js-pete/57/artifact/build/angular.js
問題は、ng-model
がinput
でどのように動作し、name
オブジェクトを上書きするかによって、ng-repeat
が失われることにあるようです。
回避策として、次のコードを使用できます。
<div ng-repeat="name in names">
Value: {{name}}
<input ng-model="names[$index]">
</div>
それが役に立てば幸い
私はそれが魅力のように働いた私の問題のために上記の解決策を試しました。ありがとう!
http://jsfiddle.net/leighboone/wn9Ym/7/
これが私のバージョンです:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.models = [{
name: 'Device1',
checked: true
}, {
name: 'Device1',
checked: true
}, {
name: 'Device1',
checked: true
}];
}
そして私のHTML
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<h1>Fun with Fields and ngModel</h1>
<p>names: {{models}}</p>
<table class="table table-striped">
<thead>
<tr>
<th></th>
<th>Feature 1</td>
<th>Feature 2</th>
<th>Feature 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Device</td>
<td ng-repeat="modelCheck in models" class=""> <span>
{{modelCheck.checked}}
</span>
</td>
</tr>
<tr>
<td>
<label class="control-label">Which devices?</label>
</td>
<td ng-repeat="model in models">{{model.name}}
<input type="checkbox" class="checkbox inline" ng-model="model.checked" />
</td>
</tr>
</tbody>
</table>
</div>
</div>