将动态字段数据从一个组件发送到另一个组件

时间:2019-10-31 08:52:07

标签: javascript angular typescript angular-reactive-forms

我正在使用反应形式来动态创建一些字段,这些字段是嵌套的动态字段,首先我创建一个数组,然后根据该新创建的数组的大小,在将数据输入后生成了其他一些输入字段现在我想将字段发送到另一个组件。我试图在这里使用viewProviders选项,但由于某些原因,它在这里不起作用。 基本上我想实现这一目标。 https://stackblitz.com/edit/angular-xusdev SecondComponent.html

<form [formGroup]="dynamicForm" (ngSubmit)=" returnVariantTo()" >
  <div class="variants-attr-row mt-1">

    <div>
      <label>
        <div *ngFor="let t of a.controls; let i = index"  class="field-heading">Attribute (e.g. 
Colour)
      <div [formGroup]="t" >
        <select formControlName="attribute"  class="attr-dropdown">
          <option *ngFor="let value of attribute" [ngValue]="value.id">
            {{ value.name }}
          </option>
        </select>     

      <div class="flex-one">
        <label>
         <div class="field-heading">Value (e.g. Red, Blue, Green)</div>
       <p-chips inputStyleClass="full-width theme-input"  max=5  formControlName="value" ></p-chips>
        </label>
      </div>
    </div> 
      </div>
     </label>
</div>
</div>
<div class="add-variantes-row">
<div>
<a>
<div class="add-variant-btn"> + </div>
   <div class="ml-2 pointer" (click)="addAttitubute()">Add Variant</div>
</a>
</div>
<div>
  <button type="submit" class="btn theme-btn " *ngIf="save">
    Save
  </button>
</div>
 </div>
<div class="variant-accordion-container" *ngFor="let data of d.controls; let i = index">

<div class="variant-heading-row">
  <div class="variant-att-first-col">Variant Name</div>
  <div class="variant-att-second-col">Retail Price</div>
  <div class="variant-att-third-col">Cost Price</div>
  </div>
<div  class="accordion" id="accordionExample">
   <div [formGroup]="data">
   <div class="card">
   <div id="headingOne">                                           
   <div class="variant-accordion-row">
   <div class="variant-att-first-col" >Mobile</div>
   <div class="variant-att-second-col"><input type="number" formControlName="retailPrice"></div>
   <div class="variant-att-third-col"><input type="number" formControlName="costPrice" ></div>
   </div>
    </div>
     </div>
      </div> 
       </div>   
</form>

SecondComponent.ts

@Component({
    templateUrl: 'product-variant.component.html',
    selector: 'product-variant',
    providers:[FormBuilder, AttributeService],
    viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class ProductVariantComponent implements OnInit {
    @ViewChild('content1') private content1;
    @ViewChild('content2') private content2;
    array=[];
    value=[];
    save= false;
    attribute = new Attribute();
    dynamicForm;
    submitted = false;
    variant = new Variant();
    @Output() returnVariant= new EventEmitter();
    isCollapsed = true;
    constructor(
        private modalService: NgbModal,
        private variantSerice: VariantService,
        private formBuilder: FormBuilder,
        private attributeService: AttributeService,
        @Host() private parentFor: FormGroupDirective 
    ) { }
    ngOnInit() {

        this.dynamicForm = this.parentFor.form;
        this.dynamicForm = this.formBuilder.group({
            attributes: new FormArray([]),
            data: new FormArray([])
        });

    }
    get f() { return this.dynamicForm.controls; }
    get a() { return this.f.attributes as FormArray; }
    get d() { return this.f.data as FormArray; }

    addAttitubute(){

        this.attributeService.getAttributes().subscribe(response =>{
            this.save = true;
            this.attribute=response;
            if(this.a.length < 3){
                this.a.push(this.formBuilder.group({
                    attribute: new FormControl (""),
                    value: new FormControl("")
                }));
            } else {
                console.log("Cant add more");
            }
        }) 

    }

    returnVariantTo() {
    this.array=null
    let obj=[];
    let temp=[];
    obj.push(this.dynamicForm.value.attributes);
    obj.forEach(x=>{
     x.forEach(y=>{
         temp.push(y.value);
     })
    })

    this.array = this.allPossibleCases(temp);
    this.createForm(this.array);
    console.log(this.dynamicForm.value);
    }
    // this.returnVariant.emit(this.variant)

    createForm(arr:any[]){
        for (let i = 0; i < arr.length; i++) {
            this.d.push(this.formBuilder.group({
                retailPrice: ['', Validators.required],
                costPrice: ['', Validators.required],
                startingInventory: ['', Validators.required],
                reorderLevel: ['', Validators.required],
                reorderQuantity: ['', Validators.required],
                tax: ['',Validators.required]
            }));
        }
    }
    allPossibleCases(arr) {
        if (arr.length === 0) {
          return [];
        } 
      else if (arr.length ===1){
      return arr[0];
      }
      else {
          let result = [];
          let allCasesOfRest = this.allPossibleCases(arr.slice(1)); 
          for (var c in allCasesOfRest) {
            for (var i = 0; i < arr[0].length; i++) {
              result.push(arr[0][i] + allCasesOfRest[c]);
            }
          }
          return result;
        }

      }


} 

FirstComponent.html

 <form (ngSubmit)="onSubmit()" [formGroup]="detailsForm"> 
   <product-variant></product-variant>
   <button type="submit">Save</button>
 </form>  

FirstComponent.ts

@Component({
templateUrl: 'product-add.component.html',
 providers:[BarcodeService, VariantService],
 viewProviders:[{provide:ControlContainer,useExisting: FormGroupDirective }]

})
@Injectable()
export class ProductAddComponent implements OnInit{
detailsForm = new FormGroup({});
constructor(
  ) { }
ngOnInit() {}
 onSubmit(){
  console.log(this.detailsForm.value);
  }
}

1 个答案:

答案 0 :(得分:1)

基本上,如果您想从childparent组件进行通信,则应该使用EventEmitter

Child.component.ts

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

@Output() emitEventToParent: EventEmitter<any> = new EventEmitter();
this.emitEventToParent.emit("{valule to be emitted}");

Parent.Component.html

<app-child (emitEventToParent)="captureEvent($event)"></app-child>

Parent.Component.ts

captureEvent(value){
 //Your logic goes here
}