嘗試使用 ngFor 把陣列綁定在input上時遇到的奇特現象

<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打了一個字,就會跳開,沒辦法正常好好地輸入文字去更改。

後來找著找著找到這個問題

注意到回覆的解答在ngFor裡面多了 trackBy:trackByIndex; 然後componet裡面也有相對應的程式碼

雖然下方有人回覆說 trackBy 這個參數在 template 上面根本沒用到,

但是我學著在 template 和 component 上加上之後,input 就可以正常的打完所想要打的內容了!!

雖然是解決了問題,可是想要詢問這個問題產生和解決的的原由是甚麼呢?謝謝!! :sob:

附上那個解答的範例程式

可以發現如果把 trackBy 拿掉,也會發生input 輸入一個字就會跳開的問題。

trackBy 是提供給 ngForOf 本身使用,而不是在 template 上面使用

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.