0

Consider the following scenario. I want to use three NameInputComponent, which each wrap a text input, to construct a FullNamesComponent:

  • Two NameInputComponents, for a pair of individual first names (firstName1 & firstName2)
  • One NameInputComponent, for a shared last name (sharedLastName)

The FullNamesComponent should expose two full names:

  • fullName1 = firstName1 + ' ' + sharedLastName
  • fullName2 = firstName2 + ' ' + sharedLastName

What would be the proper way to link these components together? I have tried using ngModel, which allows me to bind the value of the input to a variable in the NameInputComponent, but I'm at a loss for how to keep building up so I can do something with these values in a parent component. From what I understand, I need to use an EventEmitter to make the value consumable from a parent, but I'm not sure how to go about this.

I should note this isn't being used as a form to be submitted. I'm looking to bind to the outputs and use them for other portions of the page, as well as be able to change the content of the inputs programmatically/via bindings to other sections of the page.

Here is what I have so far:

name-input.component.ts

import {Component} from 'angular2/core';

@Component({
  selector: 'name-input',
  template: `
    <h2>{{inputValue}}</h2>
    <input type="text" [(ngModel)]="inputValue">
  `
})
export class NameInputComponent {
  inputValue: string; // <= How do I detect changes to this?
}

full-names.component.ts

import {Component} from 'angular2/core';

@Component({
  selector: 'full-names',
  template: `
    {{fullName1}} &amp; {{fullName2}}
    <name-input #firstName1></name-input>
    <name-input #firstName2></name-input>
    <name-input #sharedLastName></name-input>
  `,
  directives: [
    NameInputComponent
  ],
  providers: [
    NameInputComponent
  ]
})
export class FullNamesComponent {
  fullName1: string; // No idea how to link these
  fullName2: string; // to values in components above
}
bosticko
  • 763
  • 9
  • 21

1 Answers1

0

I would consider something like this.

Assume you want to have FullNamesComponent to listen to the event (change) on the NameInputComponent

import {Component, EventEmitter} from 'angular2/core';

@Component({
  selector: 'name-input',
  template: `
    <h2>{{inputValue}}</h2>
    <input type="text" [(ngModel)]="inputValue" ()="nameChanged.emit($event.target.value)">
  `,
  outputs: ['nameChanged']
})
export class NameInputComponent {
  inputValue: string; // <= How do I detect changes to this?
  nameChanged = new EventEmitter<string>();
}

then FullNamesComponent would be similar to

import {Component} from 'angular2/core';

@Component({
  selector: 'full-names',
  template: `
    {{fullName1}} &amp; {{fullName2}}
    <name-input #firstName1 (nameChanged)="firstName1Changed($event)"></name-input>
    <name-input #firstName2 (nameChanged)="firstName2Changed($event)"></name-input>
    <name-input #sharedLastName (nameChanged)="sharedLastNameChanged($event)"></name-input>
  `,
  directives: [
    NameInputComponent
  ],
  providers: [
    NameInputComponent
  ]
})
export class FullNamesComponent {
  firstName1: string; 
  firstName2: string; 
  sharedLastName: string;

  firstName1Changed(inName: string) {
     this.fullName1 = inName;
     // do something
  }
  firstName2Changed(inName: string) {
     this.fullName2 = inName;
     // do something
  }
  sharedLastNameChanged(inName: string) {
     this.sharedLastName = inName;
     // do something
  }
}

last, I do not think you need to specify providers: [NameInputComponent] in FullNamesComponent since NameInputComponent is a Directive you use in the template of FullNamesComponent and is not as part of the DependencyInjection mechanism.

I hope I have understood your point and that this helps

Picci
  • 16,775
  • 13
  • 70
  • 113