キーワード

  • Angular2
  • ngFor
  • ngModel
  • 双方向バインディング

現象

次のように、foreachしている変数itemを双方向バインドできない。

<div *ngFor="let item of list">
  <input [(ngModel)]="item">
</div>

次のエラー。

Unhandled Promise rejection: Cannot assign to a reference or variable! ; Zone: <root> ; Task: Promise.then ; Value: Error: Cannot assign to a reference or variable!
   at _AstToIrVisitor.visitPropertyWrite (http://localhost:4200/main.bundle.js:40987:23)
   at PropertyWrite.visit (http://localhost:4200/main.bundle.js:24973:24)
   at ASTWithSource.visit (http://localhost:4200/main.bundle.js:25159:25)
   at convertCdStatementToIr (http://localhost:4200/main.bundle.js:40784:28)
   at CompileEventListener.addAction (http://localhost:4200/main.bundle.js:59420:135)
   at http://localhost:4200/main.bundle.js:59490:18
   at Array.forEach (native)
   at collectEventListeners (http://localhost:4200/main.bundle.js:59487:16)
   at ViewBinderVisitor.visitElement (http://localhost:4200/main.bundle.js:59907:108)
   at ElementAst.visit (http://localhost:4200/main.bundle.js:8912:24)
   at http://localhost:4200/main.bundle.js:9042:29 Error: Cannot assign to a reference or variable!
   at _AstToIrVisitor.visitPropertyWrite (http://localhost:4200/main.bundle.js:40987:23)
   at PropertyWrite.visit (http://localhost:4200/main.bundle.js:24973:24)
   at ASTWithSource.visit (http://localhost:4200/main.bundle.js:25159:25)
   at convertCdStatementToIr (http://localhost:4200/main.bundle.js:40784:28)
   at CompileEventListener.addAction (http://localhost:4200/main.bundle.js:59420:135)
   at http://localhost:4200/main.bundle.js:59490:18
   at Array.forEach (native)
   at collectEventListeners (http://localhost:4200/main.bundle.js:59487:16)
   at ViewBinderVisitor.visitElement (http://localhost:4200/main.bundle.js:59907:108)
   at ElementAst.visit (http://localhost:4200/main.bundle.js:8912:24)
   at http://localhost:4200/main.bundle.js:9042:29

原因

分からないが、次の見解がある。

I think ngFor don't like tracking array elements

対策

インデックスを利用して配列の要素をバインドする

foreachしている変数をバインドすることはできないが、コレクションにインデックスを指定して得られる要素はバインドすることができる。

<div *ngFor="let item of list; let i = index">
  <input [(ngModel)]="list[i]">
</div>

または、配列の要素をオブジェクトにしてプロパティをバインドする

foreachしている変数をバインドすることはできないが、その変数(オブジェクト)のプロパティはバインドすることができる。

this.list = [
  {data: 'xxx'},
  {data: 'yyy'},
  {data: 'zzz'}
];
<div *ngFor="let item of list">
  <input [(ngModel)]="item.data">
</div>

参考


Last-modified: 2016-11-08 (火) 10:12:14 (69d)