2016-03-23 18 views
0

角度2のクロスコンポーネント通信を把握しようとしていますが、今は失敗しています。基本的に私は3つのコンポーネントを持っています:この場合は親であるAddProductコンポーネント、サービスを使用してカテゴリのリストをドロップダウンに取り込むCategorySelectorコンポーネント、カテゴリをパラメータとしてドロップダウンを設定するProductSelectorコンポーネント選択されたカテゴリに属する​​製品のリスト。角2:コンポーネントAがコンポーネントBを更新するとき

私が理解しようとしているのは、ProductSelectorがProductSelectorを変更して新しい製品リストを取得するために必要な機能を実行するようにする方法です。ここで

は私のコードです:

アドオンproduct.html

<h1 class="ui header">Add product</h1> 

<form class="ui form"> 
    <div class="four wide field"> 
    <label>Category</label> 
    <category-selector (selection)="setCategory($event)" defaultText="Please Choose a Category"></category-selector> 
    </div> 
    <div class="four wide field" *ngIf="selectedCategory"> 
    <label>Product</label> 
    <product-selector (selection)="setProduct($event)" [category]="selectedCategory" defaultText="Select a Product"></product-selector> 
    </div> 
</form> 

アドオンproduct.component.ts

import {Component, OnInit, NgZone} from 'angular2/core'; 
import {StoreProduct} from './storeproduct.service'; 
import {Product} from './product.service'; 
import {CategorySelector} from './category-selector.component'; 
import {ProductSelector} from './product-selector.component'; 

declare var __resourcePath: string; 

@Component({ 
    selector: 'add-product', 
    templateUrl: __resourcePath + '/html/add-product.html', 
    providers: [Product, StoreProduct], 
    directives: [CategorySelector, ProductSelector] 
}) 
export class AddProduct { 

    public categories: string[]; 
    public selectedCategory: string; 
    public selectedProduct: Product__c; 

    constructor(private storeproduct: StoreProduct, private product: Product, private zone: NgZone) {} 

    setCategory(selection: string) { 
     this.selectedCategory = selection; 
    } 

    setProduct() { 

    } 

} 

製品-selector.component.ts

import {Component, Input, Output, EventEmitter, OnInit} from 'angular2/core'; 
import {Product} from './product.service'; 

@Component({ 
    selector: 'product-selector', 
    template: ` 
     <select #sel (change)="selection.emit(sel.value)" class="ui fluid dropdown"> 
      <option value="" selected>{{defaultText}}</option> 
      <option *ngFor="#product of products" value="{{product}}">{{product.Name}}</option> 
     </select> 
    `, 
    providers: [Product] 
}) 
export class ProductSelector implements OnInit { 

    @Output() selection = new EventEmitter(); 
    @Input() defaultText: string = 'No product selected'; 
    @Input() category: string; 

    private products: Product__c[]; 

    constructor(private product: Product) {} 

    fetchProducts() { 
    let source = this.product.fetch(this.category); 
     let sub = source.toPromise().then((val: JSForce.SOQLQueryResult<Product__c>) => { 
      this.products = val.records; 
     }); 
    } 

    ngOnInit(): any { 
    this.fetchProducts(); 
    } 

} 

カテゴリ--selector.com ponent.ts

+2

ProductSelectorでngOnChangesライフサイクルフックを実装して、カテゴリ入力プロパティが変更されたときにいつでも 'fetchProducts'を実行することができます。うまくいくと思います。 – rrjohnson85

+0

@ rrjohnson85私は文字通りそれを見つけました!先週はどこにいたのですか?ハハ – watzon

+0

ハハ、何か似たようなことをしたとき、私は一週間ほど前にそれを見つけました。私はフックをもっと深く探検する必要がある、私は彼らが後でより早く便利に来ると確信している。 – rrjohnson85

答えて

1

成分Aと成分Bは兄弟であり、あなたはBを通知したいので

import {Component, Input, Output, EventEmitter, OnInit} from 'angular2/core'; 
import {StoreProduct} from './storeproduct.service'; 

@Component({ 
    selector: 'category-selector', 
    template: ` 
     <form class="ui form"> 
      <select #sel (change)="selection.emit(sel.value)" class="ui fluid dropdown"> 
       <option value="" selected>{{defaultText}}</option> 
       <option *ngFor="#category of categories" value="{{category}}">{{category}}</option> 
      </select> 
     </form> 
    `, 
    providers: [StoreProduct] 
}) 
export class CategorySelector implements OnInit { 

    @Output() selection = new EventEmitter(); 
    @Input() defaultText: string = 'No category selected'; 

    categories: string[]; 

    constructor(private sp: StoreProduct) {} 

    ngOnInit(): any { 

     let source = this.sp.fetchCategories(); 
     let sub = source.toPromise().then((val: string[]) => { 
      this.categories = val; 
     }); 
    } 

} 
は、次の2つの選択肢があります。

  • がアップし、親にAからイベント/値を放ち、値の変更時にBでロジックを実行する必要がある場合は、ライフサイクルフックngOnChanges()を実装します(@ rrhohnson85はすでにコメントに記載されています)。私はセッターの内部でこのロジックをトリガーすることはお勧めしません。
  • 共有サービス(コメントで@ rrhohnson85で既に述べられている)をSubjectまたはObservableとともに使用します。コンポーネントAは、SubjectまたはObservableのnext()を呼び出すサービス上のメソッドを呼び出します。コンポーネントBは、Subject/Observableへのsubscribe()の変更/イベントの通知を受けます。
    Subjectを使用する例については、cookbookを参照してください。
    Observableを使用した例については、このSOの質問Delegation: EventEmitter or Observable in Angular2を参照してください。
関連する問題