<tr *ngFor="let place of user.places; let i = index; ">
<td>{{i+1}}</td>
<td>
<md-input-container class="ct-full-input">
<input mdInput type="text" name="{{'place' + i}}" [(ngModel)]="user.places[i]">
</md-input-container>
</td>
<td>
<button md-icon-button (click)="deletePlace(place)"><md-icon>delete</md-icon></button>
</td>
</tr>
最近在嘗試把陣列的資料使用[(ngModel)]的方式綁在input上面,但是遇到一個奇特的現象,
就是當我像上述的代碼去使用的時候,input打了一個字,就會跳開,沒辦法正常好好地輸入文字去更改。
後來找著找著找到這個問題
angular, typescript
注意到回覆的解答在ngFor裡面多了 trackBy:trackByIndex;
然後componet裡面也有相對應的程式碼
雖然下方有人回覆說 trackBy
這個參數在 template 上面根本沒用到,
但是我學著在 template 和 component 上加上之後,input 就可以正常的打完所想要打的內容了!!
雖然是解決了問題,可是想要詢問這個問題產生和解決的的原由是甚麼呢?謝謝!!
附上那個解答的範例程式
可以發現如果把 trackBy
拿掉,也會發生input 輸入一個字就會跳開的問題。
trackBy 是提供給 ngForOf 本身使用,而不是在 template 上面使用
* ### Change Propagation
*
* When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM:
*
* * When an item is added, a new instance of the template is added to the DOM.
* * When an item is removed, its template instance is removed from the DOM.
* * When items are reordered, their respective templates are reordered in the DOM.
* * Otherwise, the DOM element for that item will remain the same.
*
* Angular uses object identity to track insertions and deletions within the iterator and reproduce
* those changes in the DOM. This has important implications for animations and any stateful
* controls (such as `<input>` elements which accept user input) that are present. Inserted rows can
* be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state
* such as user input.
*
* It is possible for the identities of elements in the iterator to change while the data does not.
* This can happen, for example, if the iterator produced from an RPC to the server, and that
* RPC is re-run. Even if the data hasn't changed, the second response will produce objects with
* different identities, and Angular will tear down the entire DOM and rebuild it (as if all old
* elements were deleted and all new elements inserted). This is an expensive operation and should
This file has been truncated. show original
trackBy 是提供 ngFor 一個追蹤異動時的一個規則。每一次的改變,ngFor 會去比較差異
An optional function passed into NgForOf that defines how to track items in an iterable (e.g. fby index or id)
TrackByFuncton API
2個讚
原來如此,剛剛額外發現,
當我用的是物件型陣列去綁input的時候,沒有加TrackBy 卻沒有發生打一個字就跳掉的動作,
只有用在純字串陣列去綁input的時候,就需要多加 TrackBy 才能避免發生跳掉的情況。
1個讚
提供官方文件中相關的片段: *ngFor with trackBy
物件型不需要加 TrackBy 應該是因為 instance 未變,#2 Kevin 擷取的部分有提到:
Angular uses object identity to track insertions and deletions within the iterator and reproduce those changes in the DOM.