Angular 2: envío del formulario cancelado porque el formulario no está conectado

82

Tengo un modal que contiene un formulario, cuando se destruye el modal, aparece el siguiente error en la consola:

Envío de formulario cancelado porque el formulario no está conectado

El modal se agrega a un <modal-placeholder>elemento que es hijo directo de <app-root>mi elemento de nivel superior.

¿Cuál es la forma correcta de eliminar un formulario del DOM y deshacerse de este error en Angular 2? Actualmente usocomponentRef.destroy();

mella
fuente
¿Tenías un * ngIf que esconde y muestra el formulario?
mickdev
@mickdev no * ng Si destruyo el modal así componentRef.destroy();, agregué más detalles a mi pregunta. ¡Gracias!
nick
2
@mickdev, ¿qué debo hacer si uso * ngif para ocultar y mostrar el formulario?
711

Respuestas:

179

Puede haber otras razones por las que esto ocurre, pero en mi caso tenía un botón que el navegador interpretó como un botón de envío y, por lo tanto, el formulario se envió cuando se hizo clic en el botón que causó el error. Agregar type = "button" solucionó el problema. Elemento completo:

    <button type="button" (click)="submitForm()">
Erik Lindblad
fuente
33
No estoy seguro de por qué se aceptó esta respuesta, porque al hacer esto, pierde la capacidad de presionar Intro para enviar el formulario.
Peter LaBanca
7
La respuesta de Nour es la más sencilla y permite introducir la tecla.
Heiner
2
Esto solucionó mi problema en el que estaba implementando un botón CANCELAR en el formulario que eliminó el formulario de la página a través de una directiva * ngIf. Tengo un botón GUARDAR que activa la lógica para eliminar también el formulario (al guardarlo correctamente) pero este mensaje de error nunca apareció con él aunque no tengo el tipo = 'botón'.
AlanObject
3
En mi caso, este error estaba ocurriendo en un botón Cancelar, por lo que es bueno que agregué type="button":)
Marcos Lima
Creo que esta respuesta es buena porque debe ser explícito en sus formularios sobre qué botón es el botón de enviar. Resuelve este problema del botón incorrecto que se usa para el envío y le permite continuar usando la tecla Intro para los envíos.
Justin
80

En la etiqueta del formulario debe escribir lo siguiente:

 <form #myForm="ngForm" (ngSubmit)="onSubmit()">

y dentro del formulario debe tener el botón de enviar:

 <button type="submit"></button>

Y lo más importante, si tiene otros botones en su formulario, debe agregarlos type="button". Dejar el typeatributo predeterminado (que creo que es submit) provocará el mensaje de advertencia.

<button type="button"></button>
Nour
fuente
2
Creo que # myForm = "ngForm" no es necesario.
Heiner
Tiene razón, a menos que necesite la referencia al ngForm, no es necesario.
Nour
Esta es la forma correcta de resolverlo. Esto elimina el mensaje mientras mantiene la capacidad de enviar presionando enter.
William Stevens
24

Así que en realidad me encontré exactamente con el mismo problema hoy, excepto sin un modal involucrado. En mi forma, tengo dos botones. Uno que envía el formulario y otro que, al hacer clic, vuelve a la página anterior.

<button class="btn btn-default" routerLink="/events">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</button>

Hacer clic en el primer botón con routerLink hace exactamente lo que se supone que debe hacer, pero aparentemente también intenta enviar el formulario y luego tiene que abandonar el envío del formulario porque la página en la que estaba el formulario se desmonta del DOM durante el envío.

Esto parece ser exactamente lo mismo que le está sucediendo, excepto con un modal en lugar de la página completa.

El problema se soluciona si especifica directamente el tipo del segundo botón para que sea diferente a enviar.

<button type="button "class="btn btn-default" routerLink="/events">Cancel</button>

Entonces, si está cerrando el modal a través de un botón 'Cancelar' o algo por el estilo, especificar el tipo de ese botón, como se muestra arriba, debería resolver su problema.

Darkrender
fuente
6

En el elemento de formulario, debe definir el método de envío (ngSubmit), algo como: <form id="currency-edit" (ngSubmit)="onSubmit(f.value)" #f="ngForm">

y en el botón enviar, omite el método de clic, porque su formulario ahora está conectado al método de envío: <button class="btn btn-success" type="submit">Save</button>el botón debe ser del tipo de envío.

En el código detrás del componente, implementa el método "onSubmit", por ejemplo, algo como esto: onSubmit(value: ICurrency) { ... } Este método recibe un objeto de valor con valores de los campos del formulario.

Igor Babic
fuente
Gracias, esta debería ser la respuesta aceptada si aún desea utilizar el tipo de botón = "enviar" en su formulario
Fjut
4

En caso de que el envío del Formulario vaya acompañado de la destrucción del componente, el envío del Formulario falla en la condición de carrera con la separación del Formulario del DOM. Di que tenemos

submitForm() {
  if (this.myForm.invalid) {
    return;
  }
  this.saveData(); // processing Form data
  this.abandonForm(); // change route, close modal, partial template ngIf-destroying etc
}

Si saveDataes asincrónico (por ejemplo, guarda los datos a través de una llamada a la API), entonces podemos esperar el resultado:

submitForm() {
  this.saveDataAsync().subscribe(
    () => this.abandonForm(),
    (err) => this.processError(err) // may include abandonForm() call
  );
}

Si necesita abandonar el formulario de inmediato, también debería funcionar un enfoque de retraso cero. Esto garantiza que la separación de DOM esté en el siguiente ciclo de eventos después de que se haya llamado al envío del formulario:

submitForm() {
  this.saveData();
  setTimeout(() => this.abandonForm());
}

Esto debería funcionar independientemente del tipo de botón.

dhilt
fuente
2

Tuve este problema recientemente y event.preventDefault()trabajé para mí. Agréguelo a su método de evento de clic.

<button type="submit" (click)="submitForm($event)" mat-raised-button>Save</button>

Y:

submitForm(event: Event) {
  event.preventDefault();
  // ...
}
Abubakar Ibrahim
fuente
2
No hay suficientes detalles para esta respuesta. Explique de manera convincente cómo esta solución es diferente o mejor que las otras enumeradas, ya que esta publicación ya tiene varias soluciones. Lea las pautas de SO antes de publicar.
bujía
1
@sparkplug don't gatekeep, esta respuesta fue útil, incluso si necesitaba más detalles.
Will Shaver
Will Shaver: útil, tal vez. Bien formateado y fácil de interpretar, no tanto. Existen estándares para garantizar que las respuestas sean fáciles de leer y comprender para un usuario de SO. La respuesta de @dhilt es un ejemplo de una solución con más detalle que es más fácil de seguir.
bujía
0

Veo esto en Angular 6, incluso sin botones de envío. ocurre cuando hay varios formularios en la misma plantilla. No estoy seguro de si hay una solución / cuál es la solución.

Nir
fuente
0

Tuve esta advertencia, cambié el tipo de botón "enviar" a "botón" problema resuelto.

Shahid Islam
fuente
0

Si aún desea mantener la funcionalidad del botón para que sea del tipo "enviar", entonces no debería utilizar el evento de clic en ese botón. En su lugar, debe usar el evento ngSubmit en el formulario.

Ejemplo:

<form (ngSubmit)="destroyComponent()">
<button type="submit">submit</button>
</form>
DonDaniel
fuente
-1

Tal vez se esté dirigiendo a alguna otra página en el envío de su formulario. Utilice la navegación de ruta programática, como en el ejemplo siguiente, en lugar de pasar routerlinka la plantilla:

router.navigate(['/your/router/path'])

suyash patwardhan
fuente