2016-02-10 29 views
33

2つのコンポーネント(親と子)で構成される単純なUIを作成しました。子コンポーネントの角2 ngModelが親コンポーネントのプロパティを更新する

子コンポーネントの入力ボックスにいくつかのものを入力したときのUIの機能です。値は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; 
    } 
} 

問題がある親コンポーネントの<h1>の値は変更されませんが、<p>の値が自動的に変更されます。

+1

コンポーネントを挿入しないで、 '@ Input' https://angular.io/docs/ts/latest/api/core/Input-var.htmlを使用して子コンポーネントに値を渡します。これは、テンプレートによって作成されたインスタンスですプロバイダを指定して作成するインスタンスは、2つの異なるインスタンスです。 – Langley

答えて

73

我々は、双方向のデータバインディングを達成するために、親テンプレートで[(x)]構文を使用することができます子供と一緒に。名前がxChangeのOutputプロパティを作成すると、Angularは自動的に親プロパティを更新します。私たちの子供がしかし、値を変更するたびにemit()にイベントを必要があります:私はちょうど名前が同じである必要はありませんことを実証するためにparentComponentにでsharedVarParentを使用

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

親と子。

+5

これは単なる純金です。この情報は、angular.ioウェブサイトのCookbook/Component Interactionセクションの公式文書に記載されています。 – codeepic

+3

すごい!しかし、更新は私の親の最初のものではなかった。どうやら、@Output()イベントのvar名は入力varと全く同じですが、その背後には 'Change'があることが非常に重要です。これはAngularのどこかに記述されていますか? – deadconversations

+1

@deadconversations、はい、ここに記載されています(https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngModel) - 2番目の緑色のバー・ノートにスクロールします。 –

3

イベントエミッタ通信(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

+0

彼は既に@Outputのショートカットを双方向バインディングで使用しています。彼は 'providers:[ChildCompnent]'を使って独自のコンポーネントをオーバーライドしています。これはもっと簡単です:http://plnkr.co/edit/Qo0dMzDf9HeSGHnwhl2d?p=preview – Langley

+0

@ Langley、あなたのプランナーで親プロパティ 'sharedVar'が変化することはありません。私は親に変更を加えるイベントをemit()しなければならないと思います。 –

+2

親テンプレートで '[(sharedVar)]'を使い、出力プロパティ 'sharedVarChange'に名前を付けることで、この方法を簡略化できます。興味があれば私の答えを見てください。 –

関連する問題