web-dev-qa-db-fra.com

Angular 2 ngModel dans la composante parent met à jour la propriété de composant parent

J'ai créé une interface utilisateur simple composée de deux composants (parent et enfant).

Ce que l'interface utilisateur fait, c'est que lorsque je tape des éléments dans la zone de saisie du composant Child. La valeur changera avec ngModel.

La composante enfant fonctionne bien de cette façon.

// Child Component
@Component({
    selector: 'child',
    template: `
        <p>{{sharedVar}}</p>
        <input [(ngModel)]="sharedVar">
    `
})
export class ChildComponent {
    sharedVar: string;
}

Maintenant, j'ai un composant parent pour lequel j'ai l'intention d'utiliser la même valeur que Child Component.

J'ai ajouté le composant enfant au modèle parent et utilisé l'injection de dépendance pour appeler sharedVar du composant enfant.

// Parent Component
@Component({
    selector: 'parent',
    template: `
        <h1>{{sharedVar}}</h1>
        <child></child>
    `,
    directives: [ChildComponent],
    providers: [ChildCompnent]
})
export class ParentComponent {
    sharedVar: string;
    constructor(child: ChildComponent) {
        this.sharedVar = child.sharedVar;
    }
}

Le problème est que je tape dans la zone de saisie, la valeur dans <p> change automatiquement tandis que la valeur dans <h1> ne changez pas.

48
movila

Nous pouvons utiliser la syntaxe [(x)] du modèle parent pour établir une liaison de données bidirectionnelle avec l'enfant. Si nous créons une propriété Output avec le nom xChange, Angular met automatiquement à jour la propriété parent. Nous avons besoin de emit() un événement chaque fois que l'enfant change la valeur cependant:

import {Component, EventEmitter, Input, Output} from 'angular2/core'

@Component({
    selector: 'child',
    template: `
        <p>Child sharedVar: {{sharedVar}}</p>
        <input [ngModel]="sharedVar" (ngModelChange)="change($event)">
    `
})
export class ChildComponent {
    @Input() sharedVar: string;
    @Output() sharedVarChange = new EventEmitter();
    change(newValue) {
      console.log('newvalue', newValue)
      this.sharedVar = newValue;
      this.sharedVarChange.emit(newValue);
    }
}

@Component({
    selector: 'parent',
    template: `
        <div>Parent sharedVarParent: {{sharedVarParent}}</div>
        <child [(sharedVar)]="sharedVarParent"></child>
    `,
    directives: [ChildComponent]
})
export class ParentComponent {
    sharedVarParent ='hello';
    constructor() { console.clear(); }
}

Plunker

J'ai utilisé sharedVarParent dans ParentComponent simplement pour démontrer que les noms ne doivent pas nécessairement être identiques dans parent et enfant.

98
Mark Rajcok

Vous pouvez configurer la communication de l'émetteur d'événement (outputs) de l'enfant au parent. Par exemple comme ceci:

@Component({
    selector: 'child',
    template: `
        <p>Child: {{sharedVar}}</p>
        <input [(ngModel)]="sharedVar" (ngModelChange)="change()">
    `
})
export class ChildComponent {
    @Output() onChange = new EventEmitter();
    sharedVar: string;
    change() {
        this.onChange.emit({value: this.sharedVar});
    }
}

et le composant in parent:

@Component({
    selector: 'parent',
    template: `
        <h1>{{sharedVar}}</h1>
        <child (onChange)="sharedVar = $event.value"></child>
    `,
    directives: [ChildComponent]
})
export class ParentComponent {
    sharedVar: string;
    constructor() {

    }
}

Démo: http://plnkr.co/edit/T2KH4nGKPSy6GEvbF1Nb?p=info

3
dfsq