Encontré un caso en el que la detección de cambios entra en un bucle infinito en un error.
El código en cuestión:
@Component({selector: "signup-comp"})
@View({
directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
template: `
<form #f="form" (ng-submit)='onSignUp(f.value)'>
<div ng-control-group='credentials' #credentials="form">
Login <input type='text' ng-control='login'>
Password <input type='password' ng-control='password'>
</div>
<div *ng-if="!d.valid">Credentials are invalid</div>
<div ng-control-group='personal'>
Name <input type='text' ng-control='name'>
</div>
<button type='submit'>Sign Up!</button>
</form>
`
})
La clave es la expresión !d.valid
ng-if
!d.valid
. d
no está definido y esto desencadena un bucle infinito.
Aquí hay un ejemplo completo de Plunker .
Parece que <div ng-control-group='credentials'></div>
combinado con ng-if
es suficiente para desencadenar el error.
Rastreé la causa raíz:
NgControlGroup
declara un método onInit
, que programa parte del trabajo para que se complete de forma asincrónica, a través de PromiseWrapper.resolve
.
El problema es que onInit
realidad se puede llamar varias veces; se llama si la detección de cambios se ejecuta y nunca se ha completado correctamente. Si ocurre una excepción durante la detección de cambios después de llamar a onInit
, AbstractChangeDetector.alreadyChecked
no se establecerá y onInit
se ejecutará nuevamente durante el siguiente tick. Dado que onInit
en NgControlGroup
programa el trabajo asincrónico, el siguiente tick ocurrirá inmediatamente, causando un bucle de bloqueo.
Este problema se ha bloqueado automáticamente debido a la inactividad.
Por favor, presente un nuevo problema si se encuentra con un problema similar o relacionado.
Obtenga más información sobre nuestra política de bloqueo automático de conversaciones .
_Esta acción ha sido realizada automáticamente por un bot._
Comentario más útil
Rastreé la causa raíz:
NgControlGroup
declara un métodoonInit
, que programa parte del trabajo para que se complete de forma asincrónica, a través dePromiseWrapper.resolve
.El problema es que
onInit
realidad se puede llamar varias veces; se llama si la detección de cambios se ejecuta y nunca se ha completado correctamente. Si ocurre una excepción durante la detección de cambios después de llamar aonInit
,AbstractChangeDetector.alreadyChecked
no se establecerá yonInit
se ejecutará nuevamente durante el siguiente tick. Dado queonInit
enNgControlGroup
programa el trabajo asincrónico, el siguiente tick ocurrirá inmediatamente, causando un bucle de bloqueo.