• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

236
Views
¿Por qué Angular llama a `registerOnChange` después de `ngOnDestroy` en el componente ControlValueAccessor personalizado?

Después de crear un elemento de formulario personalizado, noté que cuando me alejaba de una ruta que alojaba ese elemento de formulario personalizado, Angular llamaba al método ngOnDestroy del elemento de formulario y luego llamaba a los métodos registerOnChange y registerOnTouched del elemento de formulario. No estoy seguro de por qué llamaría a estos dos métodos en este momento, pero definitivamente no entiendo por qué los llamaría después de ngOnDestroy .

He creado una reproducción mínima de este error aquí: https://stackblitz.com/edit/angular-ivy-6jhgh6

Este comportamiento es problemático para mí porque en mi aplicación real, destruyo una instancia de un editor de CodeMirror y establezco la referencia de la variable en null , pero en el método registerOnTouched , hago referencia a esa variable. Esto da como resultado un error de referencia nula. Esto comenzó a suceder después de actualizar a Angular 12.

over 3 years ago · Santiago Trujillo
1 answers
Answer question

0

Llamar a los métodos registerOnChange y registerOnTouched después de que se haya invocado el gancho ngOnDestroy del componente es una consecuencia de llamar a FormControlName.ngOnDestroy() .

Cuando se destruye una vista, mi entendimiento de esta función es que se invocarán todos los ganchos onDestroy de la vista destruida. Entonces, es por eso que las directivas de formulario de esa vista también tendrán su onDestroy llamado.

Esto es lo que sucede en FormControlName.ngOnDestroy() :

 // `formDirective` refers to the parent `FormGroup` directive this.formDirective.removeControl(this);

Esto es lo que sucede en FormGroupDirective.removeControl() : :

 removeControl(dir: FormControlName): void { cleanUpControl(dir.control || null, dir, /* validateControlPresenceOnChange */ false); removeListItem(this.directives, dir); }

Y finalmente, cleanUpControl es desde donde se invocan los métodos registerOnChange y registerOnTouched :

 // Reverts configuration performed by the `setUpControl` control function. // Effectively disconnects form control with a given form directive. // This function is typically invoked when corresponding form directive is being destroyed. export function cleanUpControl(/* ... */) { /* ... */ const noop = () => { if (validateControlPresenceOnChange && (typeof ngDevMode === 'undefined' || ngDevMode)) { _noControlError(dir); } }; if (dir.valueAccessor) { dir.valueAccessor.registerOnChange(noop); dir.valueAccessor.registerOnTouched(noop); } /* .... */ }

Entonces, según tengo entendido, es parte del mecanismo de limpieza . De hecho, es un poco inconveniente porque esos métodos se llaman cuando se configura la vista y también cuando se destruye la vista. Supongo que la solución es verificar primero los valores nulos/indefinidos.

Si desea explorar más, puede usar la palabra clave del debugger :

 registerOnChange(fn: any): void { debugger; this.con.log(`registerOnChange (${this.id})`); }

y luego abra DevTools en el proyecto StackBlitz.

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error