次のコンポーネントを実装しました。期待どおりに動作します。それでも、ControlValueAccessor
の実装は私にとって初めてだったので、いくつかのセクションの詳細を理解せずに ブログをフォロー しなければなりませんでした。つまり、これは「動作しますが、なぜですか?!」という状況の一種です。
_@Component({ selector: ..., templateUrl: ..., styleUrls: ...,
providers: [{ provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputTextComponent),
multi: true }]
})
export class InputComponent implements ControlValueAccessor {
constructor() { }
@Input() info: string;
onChange: any = () => { }
onTouch: any = () => { }
writeValue(input: any): void {
this.info.value = input;
// this.onChange(input);
// this.onTouch();
}
registerOnChange(_: any): void { this.onChange = _; }
registerOnTouched(_: any): void { this.onTouch = _; }
setDisabledState?(state: boolean): void { }
onEdit(value: string): void { this.onChange(value); }
}
_
動作するようになったら、writeValue(...)
メソッドの2行目と3行目をコメントアウトしましたが、私が知る限り、何も壊れていませんでした。これらの呼び出しは 他のブログ によっても一貫して提案されているので、それらを省略することは不適切であると私は確信しています。しかし、私は魔法を信じておらず、物事を行う具体的な理由があることを好みます。
onChange(...)
でonTouch(...)
およびwriteValue(...)
の呼び出しを実行することが重要なのはなぜですか。何がうまくいかず、どのような状況でそれが予想されますか?
サイドクエストとして、私もコメントアウトしようとしました 他のメソッド そしてsetDisabledState(...)
を削除したとき、バナナが行くことを何も言えないことを発見しました。それはいつ問題を引き起こすと予想できますか?本当に実装する必要がありますか(括弧の前後に疑問符が付いたバージョンで、setDisabledState?(state: boolean): void { }
のようなパラメーターがありますが、setDisabledState(state: boolean)?: void { }
のようなものもあります)。
ControlValueAccessor
について詳しく説明しているこの記事を読んでください。
コンポーネントがAngularフォームの一部として使用されることになっている場合は、通常、コンポーネントにControlValueAcceessor
インターフェイスを実装する必要があります。
WriteValue(...)メソッドの2行目と3行目をコメントアウトしましたが、私が知る限り、何も壊れていませんでした。
これはおそらく、フォームディレクティブ(formControl
をカスタム入力コンポーネントにリンクするngModel
またはFormControl
)を適用していないためです。 FormControl
は、通信にwriteValue
のInputComponent
メソッドを使用します。
これが私が上で参照した記事からの写真です:
writeValue
メソッドはformControl
によって使用され、ネイティブフォームコントロールに値を設定します。 registerOnChange
メソッドはformControl
によって使用され、ネイティブフォームコントロールが更新されるたびにトリガーされると予想されるコールバックを登録します。 registerOnTouched
メソッドは、ユーザーがコントロールを操作したことを示すために使用されます。
WriteValue(...)でonChange(...)およびonTouch(...)の呼び出しを実行することが重要なのはなぜですか?何がうまくいかず、どのような状況でそれが予想されますか?
これは、ControlValueAcceessor
を実装するカスタムコントロールがAngularのFormControl
に、入力の値が変更されたか、ユーザーがコントロールを操作したことを通知するメカニズムです。
... setDisabledState(...)を削除したときに、バナナが行くことを何も言えないことがわかりました...本当に実装する必要がありますか?
インターフェイスで指定されているように、この関数は、制御ステータスが「DISABLED」に変更されたとき、または「DISABLED」から変更されたときに、フォームAPIによって呼び出されます。値に応じて、適切なDOM要素を有効または無効にする必要があります。関連するFormControl
のステータスがdisabled
になるたびに通知を受け取りたい場合は、これを実装する必要があります。その後、カスタムロジックを実行できます(たとえば、入力コンポーネントを無効にします)。
受け入れられた答えが最も中心的な質問に簡潔に答えるとは思いません。
WriteValue(...)でonChange(...)およびonTouch(...)の呼び出しを実行することが重要なのはなぜですか?
そうではありません。 writeValueでonChangeを呼び出す必要はありません。これは意図された使用法ではありません(以下のドキュメントリンクを参照)。
何がうまくいかず、どのような状況でそれが予想されますか?
何も問題がないことを期待してください。手の込んだ答え:
がonChange
の内部からwriteValue
を呼び出すと、次のことがわかります。
registerOnChange
が呼び出されていない)ためです。emitModelToViewChange = false
モデルから指定した値(受け取ったばかり)を使用してwriteValue)を再帰的に呼び出さないようにします。言い換えると、コンポーネントがwriteValueで受け取る値を何らかの方法ですぐに変更し、それらの変更をモデルに戻すためにコンポーネントに依存しない限り、onlyonsecond以降のwriteValueの呼び出しでは、writeValueからonChangeを呼び出さなくても安全です。
こちらのドキュメントの例を参照してください: https://angular.io/api/forms/ControlValueAccessor