-
-
Save ver-1000000/3d03a3e3d2c269cb5c450116c8e11407 to your computer and use it in GitHub Desktop.
import { Pipe, PipeTransform } from '@angular/core'; | |
/** | |
* `{ id: number, name: string }[]`のような、ユニークな値を持つオブジェクトの配列に対して、 | |
* 簡単に{@link https://angular.io/api/core/TrackByFunction TrackByFunction}を設定するためのパイプ。 | |
* | |
* @example | |
* <!-- `{ id: number, name: string }[]` --> | |
* <div *ngFor="let item of items; trackBy: 'id' | keyTrackBy">{{ item.id }}: {{ item.name }}</div> | |
* | |
* <!-- `{ id: number | null, name: string | null }[]` --> | |
* <input name="name" [(ngModel)]="item.name" *ngFor="let item of items; trackBy: null | keyTrackBy"> | |
*/ | |
@Pipe({ name: 'keyTrackBy' }) | |
export class KeyTrackByPipe implements PipeTransform { | |
transform<T>(key: null | keyof T): (_: number, item: T) => T | T[keyof T] { | |
return (_: number, item: T) => key == null ? item : item[key]; | |
} | |
} |
trackByに関数参照で渡すため、ジェネリクス指定できない状態なので難しそうだなと思ってました。
someArray.map(someFunction<Hoge>) ←できない
パイプを実行記述して、かつ引数itemをngForでイテレータされたitemじゃなくて、元のコレクションの添字指定にすると、AoTで検出できるんですね。
ngForでイテレータされたitemだと検出できないのは、バグっぽいですね...。
ts、型推論がいい感じにやってくれるのでいいですね〜。
ngForでイテレータされたitemだと検出できないのは、バグっぽいですね...。
これはどういうことだろう、できるのでは……? ngForの中で使っても同じかと思いますよ。(↑の確認コード、ngFor内で行わなかったのは、わかりにくいかなぁ〜と思ってのことでした。 逆にわかりにくくなってしまったのかな!?)
手元でやっているとそういう結果になるんですけど、AoTで検出できてます?
*ngFor of
はショートカットで内部的にはAngularがごにょごにょ展開してるから難しいのかなあと勝手に忖度してました!
ありがとうございます。条件・環境の何かの違いでできる場合あるのかな?と気になってたので、スッキリしました!
展開コードまでみないとダメな理由わからなさそうだな……。
ngc
の出力結果でわかりそうですが、追うの辛いw
transformの返り値としてTrackByFunctionみたいなものを返すようにしていたけど、どうしてもうまくいかないので関数を返す型をそのまま書いた……。 これによって、存在しないキーを指定したりできないようになったと思う。
型マスターが助言してくれたら嬉しい……。
ちなみに、↑のteatwoさんとのやり取りの問題はいつの間にか解消していたようです? 普通に推論効いてるっぽいです
ちょっと書きなおしてみたんですけど割といいかもしれない!?
そもそもキーにnull設定とかしねぇだろがよォって話ですしこうしようかな!!!