Частичные Реактивные формы с родительской дочерней маршрутизацией - PullRequest
0 голосов
/ 25 мая 2019

Я новичок в угловой. Мы пытаемся построить большую форму, используя Angular Reactive формы

Ссылка на стек PFA для примера. У меня есть личная форма родительского компонента и два дочерних компонента person-job и person-info, содержащие по несколько полей в каждом.

У меня две трудности, которых я не могу достичь.

1) Я хочу, чтобы пользователь полностью заполнил родительскую форму, а затем отправил ее в конце. Но если я сначала заполню информацию, а затем форму сведений о работе и вернусь к информации; детали в информации не там. Как сохранить заполненные данные в формах с использованием подхода Reactive форм. Это происходит при переходе по дочерней форме.

2) Во-вторых, я хочу объединить оба результата формы в один json и отправить его в родительский компонент формы, т.е. Как этого добиться. Теперь я могу получить

 {title: "XYZ", salary: "0000"} 
 // and
 {name: "ABC", age: "12"}

Но я хочу что-то вроде этого:

 { 
  combinedForm : {
     info:{name: "ABC", age: "12"},
     job:{title: "XYZ", salary: "0000"}
    }
 } 

 // OR

 {
  combinedForm : {
     name: "ABC", age: "12",title: "XYZ", salary: "0000"
   }
 }

Чтобы я мог отправлять или получать данные с сервера легко и за один раз.

MyStackblitz

Ответы [ 2 ]

0 голосов
/ 25 мая 2019

Вы можете использовать сервис для обмена данными формы между двумя или более компонентами.В вашем случае вы можете использовать название услуги PersonFormService.Сервис будет выглядеть так:

import { Injectable } from '@angular/core';

@Injectable()
export class PersonFormService {
  personForm: PersonForm;
  constructor() {
    this.personForm = new PersonForm();
  }

  set infoDetails(info) {
    this.personForm.info = info;
  }

  set jobDetails(job) {
    this.personForm.job = job;
  }

  get infoDetails() {
    return this.personForm.info;
  }

  get jobDetails() {
    return this.personForm.job;
  }
}

export class PersonForm {
  info: any;
  job: any;

  constructor() {
    this.job = {};
    this.info = {};
  }
}

Теперь в обоих ваших компонентах вы можете использовать сервис, подобный этому:

person-job.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { FormGroup } from '@angular/forms';
import { Validators } from '@angular/forms';
import { PersonFormService } from '../../person-form.service';
@Component({
  selector: 'app-person-job',
  templateUrl: './person-job.component.html',
  styleUrls: ['./person-job.component.css']
})
export class PersonJobComponent implements OnInit {

  constructor(private fb: FormBuilder, private formService: PersonFormService) { }

  formJob:FormGroup;
  completeForm: any;
  ngOnInit() {
    this.formJob=this.fb.group({
      title: ['',Validators.required],
      salary:['',Validators.required]});

    this.formJob.patchValue(this.formService.jobDetails);
  }
  submit(){
    console.log(this.formJob.value);
    this.formService.jobDetails = this.formJob.value;
  }
}

person-info.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { FormGroup } from '@angular/forms';
import { Validators } from '@angular/forms';
import { PersonFormService } from '../../person-form.service';
@Component({
  selector: 'app-person-info',
  templateUrl: './person-info.component.html',
  styleUrls: ['./person-info.component.css']
})
export class PersonInfoComponent implements OnInit {


  constructor(private fb: FormBuilder, private formService: PersonFormService) { }

  form:FormGroup;
  ngOnInit() {
    this.form=this.fb.group({
      name: ['',Validators.required],
      age:['']});

    this.form.patchValue(this.formService.infoDetails);
  }

  submitForm() {
    console.log("submit")
   this.formService.infoDetails = this.form.value; 
  } 

}

Теперь, чтобы ответить на второй вопрос , вы можете использовать спред оператор, чтобы объединить обе формы в одну форму.Ваш код будет выглядеть следующим образом:

this.completeForm = {...this.formService.infoDetails, ...this.formService.jobDetails }

См. Полную версию stackblitz demo здесь

0 голосов
/ 25 мая 2019

У вас есть несколько вариантов, если вы недовольны использованием маршрутизации для достижения этой цели.

Прежде чем я углублюсь в это, вам может быть проще просто использовать механизм вкладок без маршрутизации.

Самым простым решением здесь является общий сервис, который разделяет форму между компонентами.

оформить услугу типа:

@Injectable()
export class PersonFormService {
  private _form: FormGroup;
  get form() {
    return this._form;
  }
  constructor(private fb: FormBuilder) {
    this._form = this.fb.group({
      title: ['',Validators.required],
      salary:['',Validators.required],
      name: ['',Validators.required],
      age:['']});
  }
}

затем предоставьте эту услугу на вашем родительском уровне:

@Component({
  selector: 'app-person-form',
  templateUrl: './person-form.component.html',
  styleUrls: ['./person-form.component.css'],
  providers: [PersonFormService]
})

затем используйте форму в ваших компонентах:

export class PersonJobComponent implements OnInit {

  constructor(private personFormService:PersonFormService) { }

  formJob:FormGroup;
  ngOnInit() {
    this.formJob= this.personFormService.form;
  }

  submit(){
    console.log(this.formJob.value);

  }
}

и

export class PersonInfoComponent implements OnInit {


  constructor(private personFormService: PersonFormService) { }

  form:FormGroup;
  ngOnInit() {
    this.form=this.personFormService.form;
  } 

}

Теперь у вас будет вся форма в обоих ваших компонентах.

рабочий стекблиц: https://stackblitz.com/edit/angular-qrym5k

Если вы хотите обрабатывать две вложенные формы более отдельно для целей проверки или чего-либо другого, просто реструктурируйте конструкцию формы в службе на 2 группы форм.

что-то вроде:

@Injectable()
export class PersonFormService {
  private _form: FormGroup;

  get combinedForm() {
    return this._form;
  }

  get jobForm() {
    return this._form.get('job') as FormGroup;
  }

  get infoForm() {
    return this._form.get('info') as FormGroup;
  }

  constructor(private fb: FormBuilder) {
    this._form = this.fb.group({
      info: this.fb.group({
        name: ['',Validators.required],
        age:['']
      }),
      job: this.fb.group({
        title: ['',Validators.required],
        salary:['',Validators.required]
      })
    });
  }
}

тогда просто используйте personFormService.infoForm или .jobForm соответствующим образом в ваших соответствующих компонентах.

...