2016-03-23 21 views
0

bileşenini değiştirir Angular 2'de çapraz bileşen iletişimini bulmaya çalışıyorum ve şu an başarısız. Temel olarak 3 bileşenim var: bu durumda, bir alt öğe olan bir kategori, bir kategori listesiyle açılır listeyi doldurmak için bir hizmet kullanan bir CategorySelector bileşeni ve bir kategoriyi parametre olarak alan bir ProductSelector bileşeni ve bir açılır listeyle açılır Seçilen kategoriye ait Ürünlerin listesi.Köşeli 2: Bileşen A, B bileşenini güncellediğinde B

Anlamaya çalıştığım şey, ProductSelector ürününü değiştirdiğinde, ProductSelector ürününün yeni listesini almak için gerekli işlevi çalıştırması için bunu nasıl yapacağınızdır. İşte

benim kodudur:

eklenti 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> 

eklenti 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() { 

    } 

} 

ürüne 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(); 
    } 

} 

category-selector.com ponent.ts

+2

ngOnChanges kullanım ömrü kancasını ProductSelector üzerinde uygulamayı deneyebilir ve kategori girdisi özelliği her değiştiğinde 'fetchProducts' öğesini çalıştırabilirsiniz - bunun işe yarayacağını düşünüyorum. – rrjohnson85

+0

@ rrjohnson85 Gerçekten bunu sadece buldum! Bu geçen hafta nerede oldu ?! Haha – watzon

+0

Haha, Ben benzer bir şey yaparken bir hafta önce tökezledim. Kancaları daha derinlemesine incelemeliyim, eminim ki daha sonradan işe yarayacaklar. – rrjohnson85

cevap

1

bileşeni A ve B bileşeni kardeşler vardır ve bir B bildirmek istediğimiz için

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

} 
, iki seçeneğiniz vardır:

  • kadar ebeveyne A'dan bir olay/değer yayar, daha sonra B'deki bir giriş özelliğine veri girin. Değer değiştiğinde B'de bir mantığı çalıştırmanız gerekiyorsa, yaşam döngüsü kancasını ngOnChanges() (bir yorumda daha önce bahsedildiği gibi @ rrhohnson85) uygulayın. Bu mantığı bir dizinin içinde tetiklemeyi önermiyorum.
  • Bir Konuya veya Gözlemlenebilir'e sahip bir paylaşılan hizmet (bir yorumda @ rrhohnson85 tarafından da belirtilmiştir) kullanın. Bileşen A, Konuya veya Gözlemlenebilir'e next() numaralı çağrıyı yapan hizmette bir yöntem çağırır. Bileşen B, Konuya subscribe() veya değişiklik/olaylardan haberdar edilmek üzere Gözlemlenebilir.
    Konu kullanmanın bir örneği için cookbook'a bakın.
    Örnek: Gözlemlenebilir bir örnek için Delegation: EventEmitter or Observable in Angular2 numaralı soruyu inceleyin.
İlgili konular