es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Angular. Formulario Reactivo de enlace de datos bidireccional.

Después de cargar los datos, llamo al formulario de reanudación. Después de manipular los datos desde la clase de la plantilla HTML, no se ha actualizado y en este momento uso esto:

Object.assign(this.customer, this.customerForm.getRawValue());

Pero sé que esta no es la solución adecuada, y cada clave y actualización de datos por condiciones no es una buena manera. ¿Existe una solución más fácil?

Tengo una clase, por ejemplo:

export class Customer {
id: number|null = null;
short_name: string|null = null;
full_name: string|null = null;
contacts: Contact[] = [];
constructor(data?: Foo) { /* ... */ }
}
export class Contact {
id: number|null = null;
name: string|null = null;
general: boolean;
emails: {email: string|null, general: boolean}[];
phones: {phone: string|null, general: boolean}[];
}

Para crear todos los datos vacíos, para el cliente existente, se rellenan algunos campos.

Ahora creamos un formulario:

“`
// convenience getters for easy access to form fields
get controls(): {[key: string]: AbstractControl} { return this.customerForm.controls; }
get contacts(): FormArray { return this.controls.contacts as FormArray; }

emails(contact: any): FormArray { return contact.controls.emails as FormArray; }
phones(contact: any): FormArray { return contact.controls.phones as FormArray; }

private initForm(customer?: Customer) {
this.customerForm = this.formBuilder.group({
short_name: [customer?.short_name, Validators.required],
full_name: [customer?.full_name, Validators.required],
user_id: [customer?.user_id, Validators.required],
site: [customer?.site],
contacts: new FormArray([])
});
this.customer.contacts.map(c => this.addContact(c));
}
private addContact(c

Tags:  ,

Answer

  1. Avatar for davy.ai

    El problema descrito está relacionado con la actualización de datos desde la plantilla HTML después de reinicializar el formulario. La solución actual funciona, pero no se considera la mejor práctica, ya que requiere asignar manualmente cada clave con su valor.

    Una mejor solución sería enlazar directamente los controles del formulario con las propiedades correspondientes del objeto Customer. Esto se puede lograr utilizando la vinculación bidireccional de datos en la plantilla HTML.

    Para hacer esto, podemos actualizar el método initForm() para vincular los controles del formulario con el objeto Customer:

    private initForm(customer?: Customer) {
      this.customerForm = this.formBuilder.group({
        id: [customer?.id],
        short_name: [customer?.short_name, Validators.required],
        full_name: [customer?.full_name, Validators.required],
        contacts: new FormArray([])
      });
    
      this.contacts.clear();
    
      customer?.contacts.forEach(contact => {
        const emails = new FormArray(contact.emails.map(email => this.formBuilder.group(email)));
        const phones = new FormArray(contact.phones.map(phone => this.formBuilder.group(phone)));
    
        this.contacts.push(
          this.formBuilder.group({
            id: [contact?.id],
            name: [contact?.name, [
              Validators.required
            ]],
            general: [contact?.general],
            position: [contact?.position],
            comment: [contact?.comment],
            emails: emails,
            phones: phones
          })
        );
      });
    
      this.customerForm.valueChanges.subscribe(data => {
        Object.assign(this.customer, data);
      });
    }
    

    En este método actualizado, primero eliminamos el array de formularios contacts y luego agregamos cada contacto con sus correspondientes formularios secundarios de correo electrónico y teléfono. También nos suscribimos al Observable valueChanges del formulario customerForm, y actualizamos el objeto Customer con los nuevos datos del formulario utilizando Object.assign().

    Con este enfoque, podemos vincular fácilmente los controles del formulario con el objeto Customer, y cualquier actualización realizada desde la plantilla HTML se reflejará automáticamente en el objeto Customer. Esto elimina la necesidad de actualizar manualmente cada par clave-valor y hace que el código sea más eficiente y mantenible.

Comments are closed.