4

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?

2 Answers 2

4

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

Sign up to request clarification or add additional context in comments.

2 Comments

Which one is best practice to implement i.e., Output or ViewChild. If possible, kindly share the code with Output properties because I am new to Angular2.
Using Output properties is better. In this video, I was explaining how to write loosely coupled components, and I use Output in one of them: youtube.com/watch?v=tSXx4NoKEYY
3

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

7 Comments

You have shared the click event example inside child component using EventEmitter. In my example click event is available inside parent component. I want to capture child component's HTML element values on parent component's button click. I have watched your pluralsight course also. If possible share the example in plunker with my requirement.
If you would like to build a plunker demonstrating your issue, I can take a look.
I have added my code in plunker tool. Have a look. plnkr.co/edit/r3237ta1XzhM2PX09pMl?p=preview.
Then I'd recommend a service. I updated your plunker here: plnkr.co/edit/iODMVQzYwXcf5qJRR1El?p=preview
@DeborahK, Thank you for your response. The example you have given in plunker has been working fine.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.