Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Child Component HTML Element values in Parent Component in angular2?

I have used below code to access child component HTML element values in parent component during parent component's button click.

Child Component.ts:-

@Component({
  selector: 'child-component',
  template: `<md-input-container><label>Title</label><input [(ngModel)]="Title" #Title></md-input-container><md-input-container><label>Name</label><input [(ngModel)]="name" #Name></md-input-container><md-input-container class="md-block" flex-gt-sm><label>State</label><md-select [(ngModel)]="user.state" #State><md-option *ngFor="let state in states" value="{{state.abbrev}}">{{state.abbrev}}</md-option></md-select></md-input-container>`
})

export class ChildComponent {
  // some code here
}

Parent Component.ts:-

import {
    Directive,
    EventEmitter,
    Output,
    OnInit,
    ElementRef
} from '@angular/core';

@Component({
  selector: 'parent-component',
  template: `<child-component></child-component><button class="md-button md-ink-ripple" type="submit" (click)="SaveCustomerDetails()"><span class="ng-scope">Submit</span></button>`
})

export class ParentComponent {
   @ViewChild('Title') title:ElementRef;
   @ViewChild('State') state:ElementRef;
   Title: string;
   State: string;
   SaveCustomerDetails() {
     this.Title = this.title.nativeElement.value; // undefined
     this.State= this.state.nativeElement.innerHTML; // undefined
   }
}

Plunker:- https://plnkr.co/edit/r3237ta1XzhM2PX09pMl?p=preview

But I couldn't able get child component's HTML element values inside SaveCustomerDetails function. How to get entered values in parent component using ViewChild method?

like image 337
RGS Avatar asked Mar 08 '23 07:03

RGS


2 Answers

Not that I'm advocating the use of @ViewChild here (it's a tightly-coupled solution), but if you want to do it without the use of @Output properties, it's possible:

@Component({
  selector: 'child-component',
  template: `<input (change)='title=$event.target.value'>
             <input (change)='name=$event.target.value'>`
})

export class ChildComponent {
  title = "";
  name = "";
}

@Component({
  selector: 'parent-component',
  template: `<child-component #child></child-component><button type="submit" (click)="SaveCustomerDetails()">Submit</button>`,
})
export class ParentComponent {

  @ViewChild('child') myChild: ChildComponent;

  SaveCustomerDetails(){

    console.log(this.myChild.title + "" + this.myChild.name);
  }
}
}

I've modified your plunker here: https://plnkr.co/edit/mCGcIW1AVX2e9gEBzeC0?p=preview

like image 111
Yakov Fain Avatar answered Mar 11 '23 11:03

Yakov Fain


If your components have a true parent/child relationship (one is nested within the other) then you can use the @Input and @Output decorators on properties to communicate between the two components.

I have a blog post about this here: https://blogs.msmvps.com/deborahk/passing-data-to-and-raising-an-event-from-a-nested-component/

enter image description here

Here is an example of a child component with @Input and @Output decorators:

import { Component, OnChanges, Input, EventEmitter, Output } from '@angular/core';

@Component({
    selector: 'pm-star',
    templateUrl: './star.component.html',
    styleUrls: ['./star.component.css']
})
export class StarComponent implements OnChanges {
    @Input() rating: number;
    starWidth: number;
    @Output() ratingClicked: EventEmitter<string> =
            new EventEmitter<string>();

    ngOnChanges(): void {
        this.starWidth = this.rating * 86 / 5;
    }

    onClick(): void {
        this.ratingClicked.emit(`The rating ${this.rating} was clicked!`);
    }
}

You can find the complete example here: https://github.com/DeborahK/Angular-GettingStarted

In any other scenario, you can build a service to communicate between your components, like this:

@Injectable()
export class ChildDataService {
  title: string;
  name: string;
}

See this plunker for more information: https://plnkr.co/edit/iODMVQzYwXcf5qJRR1El?p=preview

like image 37
DeborahK Avatar answered Mar 11 '23 12:03

DeborahK