Skip to content

Instantly share code, notes, and snippets.

@ver-1000000
Last active September 30, 2022 00:38
Show Gist options
  • Save ver-1000000/a0bfafc81d681390c051644fdb095c32 to your computer and use it in GitHub Desktop.
Save ver-1000000/a0bfafc81d681390c051644fdb095c32 to your computer and use it in GitHub Desktop.
Angular custom pipe
import { ChangeDetectorRef, Pipe, PipeTransform } from '@angular/core';
import { toPromise } from 'なんかPromiseのライブラリとか';
/**
* PipeでPromiseを扱うときは、「impureパイプにして内部的に最新の値を持つ」みたいなアプローチを取るらしい。
* これは「Nullableなstringを受け取って、Promiseで遅延評価した結果を返す」パイプ。
*/
@Pipe({ name: 'hoge', pure: false })
export class HogePipe implements PipeTransform {
/** Promiseが解決される前に渡された整形前の値。 */
private previousValue: string | undefined | null = null;
/** 計算したPromise内の値。 */
private latestReturnedValue: string | null = null;
constructor(private cdr: ChangeDetectorRef) {}
transform(value?: string | null): string | null {
if (value !== this.previousValue) {
if (value != null) { toPromise(value).then(x => this.updateLatestReturnedValue(value, x)); }
this.previousValue = value;
this.latestReturnedValue = null;
return this.transform(value);
}
return this.latestReturnedValue;
}
/**
* 変更予定の値に変わりがなければ、updateされるべき値が有効なので`this.latestReturnedValue`を更新。
* そうでなければ、何もしない。
*/
private updateLatestReturnedValue(value: string, returnedValue: string): void {
if (value === this.previousValue) {
this.latestReturnedValue = returnedValue;
this.cdr.markForCheck();
}
}
}
@ver-1000000
Copy link
Author

asyncパイプを参考にしました。 https://github.com/angular/angular/blob/master/packages/common/src/pipes/async_pipe.ts

WrappedValueが死ぬときのコミットもちょっと参考になりました。 angular/angular@49be32c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment