Подтвердить что ты не робот

Angular 2 ngСообщение в родительском компоненте обновлений дочерних компонентов

Я создал простой пользовательский интерфейс, состоящий из двух компонентов (родительский и дочерний).

Что делает пользовательский интерфейс, так это при вводе некоторого материала в поле ввода дочернего компонента. Значение изменится с помощью ngModel.

Детский компонент отлично работает.

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

Теперь у меня есть родительский компонент, который я намерен использовать то же значение, что и дочерний компонент.

Я добавил дочерний компонент в шаблон родителя и использую инъекцию зависимостей для вызова Child Component sharedVar.

// 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;
    }
}

Проблема заключается в том, что, когда я печатаю в поле ввода, значение в <p> изменяется автоматически, а значение в родительском компоненте <h1> не изменяется.

4b9b3361

Ответ 1

Мы можем использовать синтаксис [(x)] в родительском шаблоне для обеспечения двусторонней привязки данных с дочерним элементом. Если мы создадим свойство Output с именем xChange, Angular автоматически обновит родительское свойство. Нам нужно emit() событие, когда дочерний элемент меняет значение:

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

Я использовал sharedVarParent в ParentComponent, чтобы продемонстрировать, что имена не должны быть одинаковыми в родительском и дочернем.

Ответ 2

Вы можете настроить связь эмиттера событий (outputs) с дочернего на родительский. Например, например:

@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});
    }
}

и в родительском компоненте:

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

    }
}

Демо: http://plnkr.co/edit/T2KH4nGKPSy6GEvbF1Nb?p=info