I have read about articles in angular6, 3 ways to communicate in child to parent.if its wrong,please demonstrate if possible 1)output emitter 2)using viewchild 3)shared Service.
So here i need to understand how to communicate the viewchild from child to parent.
In below demo, have created a form in child component,when child component form is valid, that should be reflected in parent component.In this demo when components gets loaded in ngafterViewInit hook the view child value , its working as expected , but when type some thing , child component form is valid,button enabled in child form ,those changes not reflected in the parent component which needs to valid , but its not working as expected. can anyone give the best approach?
parent component.html
<h1> Parent Component</h1>
<button class="btn btn-danger " disabled="{{check}}">CheckParentEnable</button>
<div class="childComponent">
<app-child-component></app-child-component>
k2
</div>
parent component.html
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child/child.component';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
public check: boolean;
@ViewChild(ChildComponent) myname: ChildComponent;
constructor() {
}
ngAfterViewInit() {
this.check = this.myname.loginForm.valid;
}
}
Child.component.html
<h4>childComponentArea<h4>
<h1>Welcome to child component</h1>
<form [formGroup]="loginForm">
<input type="email" formControlName="email" placeholder="Email" >
<button class="btn btn-danger" [disabled]="loginForm.invalid">Submit</button>
</form>
child.component.ts
import { Component, EventEmitter, Input,Output, OnInit } from '@angular/core';
import { FormControl, FormGroup,Validators } from '@angular/forms';
@Component({
selector: 'app-child-component',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
loginForm:FormGroup;
name:string ='sahir';
constructor() { }
ngOnInit() {
this.createForm();
}
private createForm() {
this.loginForm = new FormGroup({
// tslint:disable-next-line
email: new FormControl('', [Validators.required])
});
}
k8
}
You probably need ngAfterViewChecked
life cycle hook for your requirement. ngAfterViewInit
of parent wont be called for every child component value changed, instead ngAfterViewChecked
would be called. And also you need to push the change detection
within parent into ViewChecked
life cycle hook, or else you will get ExpressionChanged
error in this line.
this.check = this.myname.loginForm.valid;
So this is the code that should work
import { Component, ViewChild, AfterViewChecked, ChangeDetectorRef } from '@angular/core';
constructor(private cdr : ChangeDetectorRef) {
}
ngAfterViewChecked() {
console.log('view checked')
this._check = this.myname.loginForm.valid;
console.log(this.myname.loginForm.valid);
this.cdr.detectChanges();
}
An also instead of disabled="{{check}}"
, use [disabled]="!check"