Search code examples
typescriptangularcomponentsparent

Angular 2 parent child comunication


I have 2 component: RegistrationComponent and RegistryComponent.

RegistrationComponent:

@Component({
selector: 'registration_page',
template: 
'<div>
    <registry_form [model]="parentModel"></registry_form>
    <label>{{parentModel}}</label>
</div>,
styleUrls: [...],
directives: [...],
providers: []
})
export class RegistrationComponent 
{
   parentModel : string;

   constructor()
   {
      this.parentModel = "parent"
   }
}

RegistryComponent:

@Component({
selector: 'registry_form',
template: 
'
  <label for="name">name {{model}}</label>
  <input [(ngModel)]="model" required >
',
styleUrls: [...],
directives: [...]
})

export class RegistryFormComponent 
{
   @Input() model;
}

When I write some text in input in RegistryComponent I can see changes but not in RegistrationComponent witch is the parent component. What I'm missing?


Solution

  • Look at this code:

    <registry_form [model]="parentModel"></registry_form>
    

    The [] part means that this will be an "input" binding type. You can make the thing work in 2 ways:

    1) Change the binding to be

    <registry_form [(model)]="parentModel"></registry_form>
                    ^     ^
    

    e.g. "banana in the box". But this is just a "syntactical sugar", so you would also need to implement an Output() modelChange property:

    @Component({
      selector: 'registry_form',
      template: `
        <label for="name">name {{model}}</label>
        <input [(ngModel)]="model" (ngModelChange)="modelChange.next($event)" required >
      `,
    })
    export class RegistryFormComponent {
       @Input() model: any;
       @Output() modelChange = new EventEmitter();
    }
    

    2) Make the parentModel an object with a name property, and pass this whole object:

    import {Component, Input, Output, EventEmitter} from '@angular/core'
    
    @Component({
      selector: 'registry_form',
      template: `
        <label for="name">name {{model.name}}</label>
        <input [(ngModel)]="model.name" required >
      `,
    })
    export class RegistryFormComponent {
       @Input() model: any;
    }
    
    @Component({
      selector: 'registration_page',
      template: `
      <div>
          <registry_form [model]="parentModel"></registry_form>
          <label>{{parentModel.name}}</label>
      </div>`,
      directives: [RegistryFormComponent],
    })
    export class RegistrationComponent {
       parentModel : any;
    
       constructor() {
          this.parentModel ={name:"parent"};
       }
    }