web-dev-qa-db-ja.com

Angular 2子コンポーネントのngModelは、親コンポーネントのプロパティを更新します

2つのコンポーネント(親と子)で構成されるシンプルなUIを作成しました。

UIが行うことは、Childコンポーネントの入力ボックスに何かを入力することです。値はngModelを使用して変更されます。

子コンポーネントはそのようにうまく機能します。

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

これで、子コンポーネントと同じ値を使用する親コンポーネントができました。

子コンポーネントを親テンプレートに追加し、依存性注入を使用して子コンポーネントの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>の値が変更されないことです。

48
movila

親テンプレートで[(x)]構文を使用して、子との双方向のデータバインディングを実現できます。 xChangeという名前のOutputプロパティを作成すると、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

ParentComponentでsharedVarParentを使用して、親と子で名前を同じにする必要がないことを示しました。

98
Mark Rajcok

子から親へのイベントエミッタ通信(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

3
dfsq