2016-08-02 1 views
1

J'essaie de créer un composant parent (nommé Action) avec deux composants enfants (Infos et Localisation) et de lier les entrées enfants au modèle parent.Angular 2 biding de données bidirectionnelles

Ceci est le modèle

export class Action{ 
    titre : string; 
    localisation = new Localisation(); 
} 

export class Localisation{ 
    region : string; 
    departement : string; 
} 

Le parent Composant

import { Component,OnInit } from '@angular/core'; 
import {InfosComponent} from './infos.component'; 
import {LocalisationComponent} from './localisation.component'; 
import {Action} from './action'; 
import { ActionService } from './action.service'; 

@Component({ 
    selector: 'form-action', 
    template: ` 

    <h1>Formulaire action {{currentAction.titre}}</h1> 
    <infos [titre]="currentAction.titre"></infos> 
    <localisation [localisation]="currentAction.localisation"></localisation> 

    <button (click)="ajouteAction(currentAction)">Ajouter</button> 

    <h2>Mes actions</h2> 
    <ul> 
     <li *ngFor="let act of actions"> 
     {{act.titre}} ({{act.localisation.region}}-{{act.localisation.departement}}) 
     </li> 
    </ul> 
    `, 
    directives: [InfosComponent,LocalisationComponent], 
    providers : [ActionService] 
}) 
export class ActionComponent implements OnInit{ 
    currentAction : Action; 
    actions : Action[]; 

    constructor(private actionService: ActionService) { 
     this.currentAction =new Action(); 
     console.log(this.currentAction); 
    } 

    ajouteAction(action){ 
    console.log (action); 
    this.actionService.saveAction(action); 
    } 

    getActions(){ 
     this.actionService.getActions().then(actions => this.actions = actions); 
    } 

    ngOnInit() { 
     this.getActions(); 
    } 
} 

Le composant de localisation

import { Component, Input } from '@angular/core'; 
import {Localisation} from './action'; 

@Component({ 
    selector: 'localisation', 
    template: ` 
    <h2>Localisation</h2> 
    <p> 
     <label for="region">Région : </label> 
     <input id="region" [(ngModel)]="localisation.region" placeholder="Région"/> 
    </p> 
    <p> 
     <label for="departement">Département : </label> 
     <input id="departement" type="text" [(ngModel)]="localisation.departement" placeholder="Département"/> 
    </p> 
    ` 
}) 
export class LocalisationComponent { 
    @Input("localisation") localisation: Localisation; 
} 

Le composant d'infos

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

@Component({ 
    selector: 'infos', 
    template: ` 
    <h2>Informations</h2> 
    <p> 
     <label for="titre">Titre : </label> 
     <input id="titre" [(ngModel)]="titre" placeholder="Titre"/> 
    </p> 

    ` 
}) 
export class InfosComponent { 
    @Input() titre: string; 
} 

Lorsque j'essaie d'effectuer une nouvelle action, l'emplacement est enregistré mais la nouvelle action ne contient pas le titre. Cela fonctionne quand je passe l'action entière au composant Infos (pas seulement le titre). Mais ce n'est pas le cas avec un type de chaîne.

+0

Je pense que vous avez affiché le même code pour le composant de localisation que pour le composant d'action - pourriez-vous s'il vous plaît mettre à jour ceci? – rinukkusu

+2

@rinukkusu vous avez tort! C'est un spot de la concurrence différence – PierreDuc

+0

@PierreDuc Haha, bien la non-différence évidente est le nom de la classe, ce qui m'a fait me demander: D – rinukkusu

Répondre

0

Vous devez utiliser @Input xxx; @Output xxxChange syntaxe pour la liaison bidirectionnelle comme indiqué ici.

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

export class LocalisationComponent { 
    @Input() localisation: Localisation; 
    @Output() localisationChange=new EventEmitter(); 

    ngOnChanges(changes: SimpleChanges){ 
     this.localisationChange.emit(changes['localisation'].currentValue); 
    } 
} 

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

export class InfosComponent { 
    @Input() titre: string; 
    @Output() titreChange=new EventEmitter(); 

     ngOnChanges(changes: SimpleChanges){ 
      this.localisationChange.emit(changes['titre'].currentValue); 
     } 
} 

Ce n'est pas un plunker demo pertinent, mais peut vous aider à comprendre cette syntaxe.

+0

J'ai essayé mais je ne sais pas comment lier le ngOnChanges à l'entrée

+0

Vous n'avez pas besoin de le déclarer n'importe où. Il suffit de l'écrire dans le composant lui-même comme indiqué. C'est l'un des hooks de cycle de vie du composant comme nous l'avons 'ngOnInit' – micronyks