web-dev-qa-db-ja.com

Angular 2で、あるコンポーネントから別のコンポーネントにオブジェクトを渡す方法は?

角度成分があり、最初の成分は2番目の成分を指令として使用します 。それらは同じモデルを共有する必要がありますobject、これは最初のコンポーネントで初期化されます。そのモデルを2番目のコンポーネントに渡す方法は?

54
Anoush Hakobyan

コンポーネント2、ディレクティブコンポーネントは入力プロパティ(TypeScriptの@inputアノテーション)を定義できます。そして、コンポーネント1はそのプロパティをテンプレートからディレクティブコンポーネントに渡すことができます。

SO answer Angular 2でマスターと詳細コンポーネント間の相互通信を行う方法は? を参照してください。

そして、入力が子コンポーネントにどのように渡されるのか。あなたの場合はそれがディレクティブです。

19
Chandermani

親から子への一方向のデータバインディングの場合は、@Inputデコレータ(スタイルガイドでは 推奨 )を使用して、子コンポーネントの入力プロパティを指定します。

@Input() model: any;   // instead of any, specify your type

親テンプレートでテンプレートプロパティバインディングを使用する

<child [model]="parentModel"></child>

オブジェクト(JavaScript参照型)を渡しているため、親コンポーネントまたは子コンポーネントでオブジェクトのプロパティに加えた変更は、両方のコンポーネントが同じオブジェクトへの参照を持つため、他のコンポーネントにも反映されます。これを Plunker で示しています。

親コンポーネントでオブジェクトを再割り当てした場合

this.model = someNewModel;

Angularは新しいオブジェクト参照を子コンポーネントに伝播します(自動的に、変更検出の一部として)。

あなたがすべきでない唯一のことは、子コンポーネント内のオブジェクトを再割り当てすることです。これを実行しても、親は依然として元のオブジェクトを参照します。 (双方向データバインディングが必要な場合は、 https://stackoverflow.com/a/34616530/215945 を参照してください。

@Component({
  selector: 'child',
  template: `<h3>child</h3> 
    <div>{{model.prop1}}</div>
    <button (click)="updateModel()">update model</button>`
})
class Child {
  @Input() model: any;   // instead of any, specify your type
  updateModel() {
    this.model.prop1 += ' child';
  }
}

@Component({
  selector: 'my-app',
  directives: [Child],
  template: `
    <h3>Parent</h3>
    <div>{{parentModel.prop1}}</div>
    <button (click)="updateModel()">update model</button>
    <child [model]="parentModel"></child>`
})
export class AppComponent {
  parentModel = { prop1: '1st prop', prop2: '2nd prop' };
  constructor() {}
  updateModel() { this.parentModel.prop1 += ' parent'; }
}

Plunker - Angular RC.2

56
Mark Rajcok

セッターを使ってデータをサービスに保存し、ゲッターを介して取得することもできます。

import { Injectable } from '@angular/core';

@Injectable()
export class StorageService {

    public scope: Array<any> | boolean = false;

    constructor() {
    }

    public getScope(): Array<any> | boolean {
        return this.scope;
    }

    public setScope(scope: any): void {
        this.scope = scope;
    }
}
13
ueman

出力アノテーションを使う

@Directive({
  selector: 'interval-dir',
})
class IntervalDir {
  @Output() everySecond = new EventEmitter();
  @Output('everyFiveSeconds') five5Secs = new EventEmitter();
  constructor() {
    setInterval(() => this.everySecond.emit("event"), 1000);
    setInterval(() => this.five5Secs.emit("event"), 5000);
  }
}
@Component({
  selector: 'app',
  template: `
    <interval-dir (everySecond)="everySecond()" (everyFiveSeconds)="everyFiveSeconds()">
    </interval-dir>
  `,
  directives: [IntervalDir]
})
class App {
  everySecond() { console.log('second'); }
  everyFiveSeconds() { console.log('five seconds'); }
}
bootstrap(App);
2
E. Fortes