変更を検出するとかなり重い計算をするAngularコンポーネントがあります。特定の@InputでAngularが検出を変更しないようにする
@Component (
selector: 'my-table',
... 400+ lines of angular template ...
)
class MyTable implements OnDestroy, AfterContentInit, OnChanges {
...
@override
ngOnChanges(Map<String, SimpleChange> changes) {
log.info("ngOnChanges" + changes.keys.toString());
_buildTableContent();
}
...
}
すべての入力がある場合は、この美しく働くString
、int
、bool
。つまり、ngOnChanges
は、これらのプロパティが実際に変更されたときにのみトリガします。
私は今だけのシンプルなString
ないデータをレンダリングするために、フィールドのいずれかにカスタムレンダラを追加する必要があると私はそれはそれが必要ならば、今決定します
@Input("customRenderer") Function customRenderer;
customRenderer
機能使用してくださいその値をそのまま返すか、値がオブジェクト/リストである場合は、その中から特定の値を取り出して、Instance of ___
の代わりに読み込み可能なStringを返します。
@Input("customRenderer")
を追加すると、ngOnChanges
は、その関数参照が変更されていなくても、すべての時間を起動します。
私は初期値が設定された後、特定のフィールドに変化検出をトリガしないように角度伝えることができる方法はありますか?
ngOnChanges
関数でcustomRenderer
が唯一の変更であるかどうかをチェックするifステートメントがありますが、変更検出は引き続き非効率的なトリガーとなります。
Angularはフックを持っていますか?フィールドがcustomRenderer
なら基本的にはオーバーライドできますが、変更検出をトリガーしないでください。 @パンカジ・パーカーの回答に基づいて
更新:
@Component (
selector: 'my-table',
... 400+ lines of angular template ...
)
class MyTable implements OnDestroy, AfterContentInit, OnChanges, DoCheck {
...
final ChangeDetectorRef cdr;
int renderOldValue = 0;
@Input() int render = 0;
MyTable(this.cdr);
@override
ngOnChanges(Map<String, SimpleChange> changes) {
log.info("ngOnChanges" + changes.keys.toString());
_buildTableContent();
}
@override
ngDoCheck() {
if (renderOldValue != render) {
cdr.reattach();
cdr.detectChanges();
cdr.detach();
renderOldValue = render;
}
}
@override
ngAfterContentInit() {
// detach table from angular change detection;
cdr.detach();
...
}
...
}
は今アイデアが手動で変更検出
<my-table
(change)="change(\$event)"
(click2)="editResource(\$event)"
[custom]="['tags', 'attributes']"
[customRenderer]="customRenderer"
[data]="data ?? []"
[debug]="true"
[editable]="enableQuickEdit ?? false"
[loading]="loading ?? true"
[render]="render ?? 0"
[rowDropdownItems]="rowDropdownItems"
[tableDropdownItems]="tableDropdownItems ?? []">
<column *ngFor="let column of visibleColumns ?? []"
[editable]="column.editable"
[field]="column.field"
[title]="column.title">
</column>
</my-table>
をトリガーするrender++
を呼び出すことですけれども違いはありません。..
私は、変更検出が誤って2つの異なる機能(おそらく関数の同等性を持つAngularまたはDartのバグ)と同じ関数参照を認識していると思います。ラッパークラスで関数をラップし、このようにして目的の動作が得られるかどうかを調べることができます。あなたの質問には、再現するのに十分な情報が含まれていません(customRendererはどこから来たのですか)。値が実際に変更されなかった場合は、高価な計算をスキップすることもできます。 –
私はマップでそれをラップアップして、それが正しく動作するようです。私の答えを見てください。 –
バグレポートの作成を検討しましたか?私は変更の検出機能の参照が変更されているかどうかを認識できる必要があります。私が想像できることは、機能が比較されるたびに、新しいテアロフが作成され、同じ機能からの2つのテアロフが同じとみなされないということです。おそらく、クラスレベルのフィールドに関数を割り当ててこのインスタンスを返すだけで、問題が解決する可能性があります。 –