I have a parent component having three instances of child component inside it.
child-product-detail.component.html
<form id="frmProduct" #frmProduct="ngForm" (ngSubmit)="onSave(frmProduct)">
<ng-content select="[buttons-view]"></ng-content>
<input type="text" id="txtProductName" name="txtProductName" [(ngModel)]="product.productName" />
</form>
child-product-detail.component.ts
onSave(form) {
let isValid = this.validate(form);
if (!isValid) return;
}
parent-product.compoment.html
<child-product-detail [product]="products[0]">
<div buttons-view>
<button type="button" (click)="saveProduct(0)" >Save</button>
</div>
</child-product-detail>
<child-product-detail [product]="products[1]">
<div buttons-view>
<button type="button" (click)="saveProduct(1)" >Save</button>
</div>
</child-product-detail>
<child-product-detail [product]="products[2]">
<div buttons-view>
<button type="button" (click)="saveProduct(2)" >Save</button>
</div>
</child-product-detail>
parent-product.component.ts
saveProduct(productId) {
let productToSave = this.products(productIndex);
// Code required to call onSave method of child component
}
Is there anyway I can call onSave method of the child component passing the form object of it?
Thanks.
CodePudding user response:
You can use the ViewChildren
decorator.
@ViewChildren(ChildProductDetailComponent)
childComponents: QueryList<ChildProductDetailComponent>;
saveProduct(productId) {
this.childComponents.get(productIndex).onSave();
}
CodePudding user response:
You can use an eventemitter.
Assuming you have the child component with an output event function like this:
<app-product-stock (outputStockEvent)="outputStockEvent($event)"></app-product-stock>
Then this would be the function in the parent:
public outputStockEvent(event){
this.stock = event
}
and in the child component:
constructor(private fb: FormBuilder) {
this.stockForm = this.fb.group({
a: '',
b: '',
c:'',
});
}
.....
ngOnInit(): void {
this.stockForm.valueChanges.subscribe(data =>{
this.outputStockEvent.emit(data)
})
}
If you then use a "Save" button in the ParentComponent, you can write the values into a final array:
public save(){
let finalObj ={ "stock":this.stock"}
}
CodePudding user response:
Yes, you can do it using the @Output
directive to emit custom events.
For example:
child-product-detail.component.ts
import { Component, EventEmitter, Output } from '@angular/core';
export class ChildProductDetailComponent {
@Output() yourEventEmitter = new EventEmitter<any>();
onSave(form) {
let isValid = this.validate(form);
if (isValid) {
this.yourEventEmitter.emit(form)
};
}
When onSave() is executed, it emit the yourEventEmitter
parent-product.compoment.html
<child-product-detail (yourEventEmitter)="saveProduct($event)">
<button type="button" (click)="onSave(0)" >Save</button>
</child-product-detail>
Than the parent component got the event and run the function saveProduct() and receiving the form by the $event.
parent-product.component.ts
saveProduct(productId) {
// the productId is the form from the child component
}
You cand learn more about it https://angular.io/api/core/EventEmitter