Componentes

FormAdmin: Formulario.

Fieldset: Manipulación de un elemento de una entidad.

Fieldset-array: Manipulación de un conjunto de elementos de una entidad.

Ejemplo

Formulario con un fieldset opcional y un fieldset-array

* Formulario de Administración

import { Component } from '@angular/core';
import { FormBuilder, FormControl } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';

import { DataDefinitionService } from '../../service/data-definition/data-definition.service';
import { AdminComponent } from '../../main/component/admin/admin.component';


@Component({
  selector: 'app-sede-admin',
  templateUrl: './sede-admin.component.html',
})
export class SedeAdminComponent extends AdminComponent {

  sync: any = {
    sede:{"domicilio":false},
    domicilio:{},
    referente_:{"sede":false}
  }

  data: any = {sede:null, domicilio:null, referente_:[]}

  constructor(protected fb: FormBuilder, protected route: ActivatedRoute, protected dd: DataDefinitionService)  {
    super(fb, route, dd);
    this.entity = "sede";

    this.adminForm.addControl('addDomicilio', new FormControl(true)); //debe definirse inicialmente en true para dar tiempo a que los fieldset se inicialicen.
    this.adminForm.addControl("referente_", this.fb.array([]));  //se inicializa el fieldset um de referentes
  }


  getData() {
    this.dd.getOrNull(this.entity, this.id).subscribe(
      sede => {
        this.adminForm.enable();
        this.data.sede = sede;

        if(sede && sede.domicilio){
          this.adminForm.controls['addDomicilio'].setValue(true);
          console.log(sede.domicilio);
          this.dd.getOrNull("domicilio", sede.domicilio).subscribe(
            domicilio => {           console.log(domicilio)
this.data.domicilio = domicilio },
            error => { console.log(error); }
          )
        } else {
          this.adminForm.controls['addDomicilio'].setValue(false);
        }
      },
      error => { console.log(error); }
    );
  }


  onSubmit() {
    this.adminForm.disable();
    let serverData: any[] = [];

    var domicilioId = null;
    console.log(this.adminForm.get('addDomicilio').value);
    if(this.adminForm.get('addDomicilio').value) {
      console.log("test")
      var domicilio = this.dd.server("domicilio", this.adminForm.value["domicilio"]);
      serverData.push({entity:"domicilio", row:domicilio});
      domicilioId = domicilio.id;
    }

    var sede = this.dd.server("sede", this.adminForm.value["sede"]);
    sede.domicilio = domicilioId;
    serverData.push({entity:"sede", row:sede});

    this.dd.process(serverData).subscribe(
      response => { console.log(response); }
    );
  }

}
<form [formGroup]="adminForm" (ngSubmit)="onSubmit()" novalidate>
<app-sede-fieldset [adminForm]="adminForm" [sync]="sync.sede" [row]="data.sede"></app-sede-fieldset>

<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" formControlName="addDomicilio"><span class="font-weight-bold"> Domicilio</span>
</label>
</div>

<app-domicilio-fieldset [adminForm]="adminForm" [sync]="sync.domicilio " [row]="data.domicilio" [enable]="adminForm.get('addDomicilio').value" ></app-domicilio-fieldset>

<app-referente-fieldset-array formArrayName="referente_" [fieldsetForm]="adminForm.get('referente_')" [sync]="sync.referente_" [rows]="data.referente_"></app-referente-fieldset-array>

<button [disabled]="adminForm.pristine || !adminForm.valid" type="submit" class="btn btn-success">Aceptar</button>&nbsp;
<button type="button" (click)="reset()" [disabled]="adminForm.pristine" class="btn btn-danger">Restablecer</button>

<p>Debug Form value: {{ adminForm.value | json }}</p>
<p>Debug Form status: {{ adminForm.status | json }}</p>
</form>

* Fieldset

import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';

import { DataDefinitionService } from '../../service/data-definition/data-definition.service';

import { FieldsetComponent } from '../../main/component/fieldset/fieldset.component';

@Component({
selector: 'app-domicilio-fieldset',
templateUrl: './domicilio-fieldset.component.html',
})
export class DomicilioFieldsetComponent extends FieldsetComponent {
constructor(protected fb: FormBuilder, protected dd: DataDefinitionService) {
super(fb, dd);
this.entity = 'domicilio';
this.fieldset = 'domicilio';
}

}
<fieldset *ngIf="fieldsetForm && enable" [formGroup]="fieldsetForm">
<div class="form-group row">
<label class="col-2 col-form-label">Calle</label>
<div class="col-10">
<input class="form-control" type="text" formControlName="calle" [ngClass]="{'is-invalid':(fieldsetForm.get('calle').invalid && (fieldsetForm.get('calle').dirty || fieldsetForm.get('calle').touched))}">
</div>
</div>
<div class="form-group row">
<label class="col-2 col-form-label">Entre</label>
<div class="col-10">
<input class="form-control" type="text" formControlName="entre" [ngClass]="{'is-invalid':(fieldsetForm.get('entre').invalid && (fieldsetForm.get('entre').dirty || fieldsetForm.get('entre').touched))}">
</div>
</div>
<div class="form-group row">
<label class="col-2 col-form-label">Numero</label>
<div class="col-10">
<input class="form-control" type="text" formControlName="numero" [ngClass]="{'is-invalid':(fieldsetForm.get('numero').invalid && (fieldsetForm.get('numero').dirty || fieldsetForm.get('numero').touched))}">
</div>
</div>
<div class="form-group row">
<label class="col-2 col-form-label">Piso</label>
<div class="col-10">
<input class="form-control" type="text" formControlName="piso" [ngClass]="{'is-invalid':(fieldsetForm.get('piso').invalid && (fieldsetForm.get('piso').dirty || fieldsetForm.get('piso').touched))}">
</div>
</div>
<div class="form-group row">
<label class="col-2 col-form-label">Departamento</label>
<div class="col-10">
<input class="form-control" type="text" formControlName="departamento" [ngClass]="{'is-invalid':(fieldsetForm.get('departamento').invalid && (fieldsetForm.get('departamento').dirty || fieldsetForm.get('departamento').touched))}">
</div>
</div>
<div class="form-group row">
<label class="col-2 col-form-label">Barrio</label>
<div class="col-10">
<input class="form-control" type="text" formControlName="barrio" [ngClass]="{'is-invalid':(fieldsetForm.get('barrio').invalid && (fieldsetForm.get('barrio').dirty || fieldsetForm.get('barrio').touched))}">
</div>
</div>
<div class="form-group row">
<label class="col-2 col-form-label">Localidad</label>
<div class="col-10">
<input class="form-control" type="text" formControlName="localidad" [ngClass]="{'is-invalid':(fieldsetForm.get('localidad').invalid && (fieldsetForm.get('localidad').dirty || fieldsetForm.get('localidad').touched))}">
</div>
</div>
</fieldset>

* FieldsetArray

import { Component } from '@angular/core';
import { FormBuilder, FormArray } from '@angular/forms';

import { DataDefinitionService } from '../../service/data-definition/data-definition.service';

import { FieldsetArrayComponent } from '../../main/component/fieldset-array/fieldset-array.component';

@Component({
selector: 'app-referente-fieldset-array',
templateUrl: './referente-fieldset-array.component.html',
})
export class ReferenteFieldsetArrayComponent extends FieldsetArrayComponent {
constructor(protected fb: FormBuilder, protected dd: DataDefinitionService) {
super(fb, dd);
this.entity = 'referente';
this.fieldset = 'referente';
}
}
<fieldset *ngFor="let form of fieldsetForm.controls; let i=index">
<div [formGroup]="form">
<div *ngIf="isSync('persona')" class="form-group row">
<label class="col-2 col-form-label">Persona</label>
<div class="col-10">
<app-fieldset-typeahead [entity]="'id_persona'" [fieldsetForm]="form" [field]="'persona'"></app-fieldset-typeahead>
</div>
</div>
<div *ngIf="isSync('sede')" class="form-group row">
<label class="col-2 col-form-label">Sede</label>
<div class="col-10">
<app-fieldset-typeahead [entity]="'sede'" [fieldsetForm]="form" [field]="'sede'"></app-fieldset-typeahead>
</div>
</div>
<button (click)="removeRow(i)" type="button" >Eliminar</button>

</div>

</fieldset>
<button (click)="addRow()" type="button" >Agregar</button>

Consideraciones

* Parámetros

* “data”: Datos

* “adminForm”: Formulario de administración

* “sync”: Parámetros de sincronización (opcional)

* “enable”: Flag de habilitación del fieldset (opcional)

* Uso de Servicio DataDefinition

Métodos habituales de inicialización: Dd.get y Dd.getAll (definidos en el Formulario). Dd.formGroup y dd.initForm (definidos en el fieldset)

Métodos habituales de procesamiento: Dd.server y Dd.process /definidos en el Formulario)