2016-11-08 10 views
0

Global Events in Angular 2を参照しています。新しいアイテムがカートに追加されたときにイベントを発行するカートサービスを実装しようとしています。私は、カートのアイテムなどの私の電話番号を表示する(カートの子ではない)別のコンポーネントと呼ばれるナビゲーションバーで、このサービスイベントにサブスクライブAngular2サービスエミッタサブスクライブ失敗

マイカートサービス:

export class CartService { 
    public itemAdded$: EventEmitter<any>; 
    ... 

    constructor(private http: Http){ 

     this.itemAdded$ = new EventEmitter(); 
     this.cart=[]; 
    } 

    addToCart(id: any): any { 

     this.itemAdded$.emit(id); 

     return this.http.get( this.myUrl + 'add' + '/' + id + '/', { withCredentials:true}) 
     .toPromise() 
     .then(response => response.json()) 

    } 
    ... 
    ... 
} 

私のナビゲーションバーコンポーネント:

私はアイテムを追加するたびに
@Component({ 
directives:[ROUTER_DIRECTIVES, Cart], 
providers:[CartService], 

}) 
export class Navbar implements OnInit{ 

    ... 
    totalCost: any; 
    cartItemCount : any; 
    addedItem: any; 

    constructor(private cartService: CartService){ 

     this.cartService.itemAdded$.subscribe((id: any) => { 
      alert(id); 
      this.onItemAdded(id); 
      this.fetchCartElements(); 
     }); 
    } 

    private onItemAdded(item: any): void { 
     // do something with added item 
     this.addedItem = item; 
    } 
... 
... 
} 

はしかし、何もcartItemCountなどが自動的に更新されますことができるように、すなわちalert(id)またはonItemAdded()自動的に呼び出されていないナビゲーションバーには起こりません。

何が問題になりますか?

+2

? –

+0

質問が正しく表示されませんでしたが、Navbarコンポーネントで[プロバイダ]に追加しました。私はそれで私の質問を更新しました。それ以外の場合、カートサービスはnavbarと直接関係ありません。 – Nitish

答えて

1

を他のproviders: [CartService]を削除します。

あなたのケースはObservableのふるまいに完全に合っていますので、プロミスとイベントエミッタを使用しないでください(これはサーバー側で実際にアイテムが追加される前に呼び出されます)。約束と

ソリューション:

をし、それを提供します。あなたが約束して、あなたの問題を解決したい場合には

、私は解決策は、あなただけの答えを得た後、イベントをトリガすることだと思いますトップレベルのモジュール(通常はAppModule)で、アプリケーション全体で1つのインスタンスしか取得できないようにします。観察可能と

ソリューション:

addToCart(id: any): Observable<any> {//Don't you have an item interface to type the object you get? 
     return this.http.get( this.myUrl + 'add' + '/' + id + '/', { withCredentials:true}) 
     .map(res => res.json()); 
    } 

そして上のごNavBar

あなたはこのサービスを提供しなかった
@Component({ 
directives:[ROUTER_DIRECTIVES, Cart] 
//Note that I removed CartService, as I said you HAVE to provide it on the AppModule, else you'll have different instances accross your application and it seems like it's not what you want. 
}) 
export class Navbar implements OnInit{ 

    ... 
    totalCost: any; 
    cartItemCount : any; 
    addedItem: any; 

    constructor(private cartService: CartService){ 
    } 

    private onItemAdded(item: any): void { 
     // do something with added item 
     this.addedItem = item; 
    } 

    public addItemToCart(id:number):void{ 
     //I guess you're adding item from a button click, the button should call this method, passing the id of the item as parameter. 
     this.cartService.addToCart(id).subscribe(this.onItemAdded); 
    } 
... 
... 
} 
+0

私の場合、私のnavbarコンポーネントにaddItemToCart(id:number)メソッドはありません。私は別のコンポーネントから呼び出します。 navbarコンポーネントでは、カート要素を単純に取得し、削除することができます。カートへの追加は、私の異なる製品コンポーネントで起こります。 – Nitish

1

@Output()の場合のみ使用してください。

あなたのシナリオは完全に

Subjectを作成し、next()を呼ぶ... Observableに適合するために、それはemit()に似ています。

import { Subject } from 'rxjs'; 

// .. 

    public itemAdded$ = new Subject<any>(); 

// .. 

    this.itemAdded$.next(id); 

サブスクリプションの部分は問題ありません。

+0

import {Subject} from 'rxjs'; 404が見つかりませんでした。しかし、私は 'rxjs/Observable'から{Observable}をインポートしています。 – Nitish

+0

これを試してみてください: 'rxjs/Subject'からの 'import {Subject} ';' – mxii

0

サービスはプロバイダごとにシングルです。CartServiceの異なるインスタンスをnavbarに注入していて、誰でも機能を呼び出すのはaddToCartです。

Navbarがアプリケーションのすべてのページに表示されると思いますので、CartServiceをグローバルにシングルトンにする方法はこちらです。

@NgModule({ 
    declarations: [ 
    ], 
    imports: [ 
    ], 
    providers: [CartService], //<--- added here 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

(あなたが別のインスタンスを作成するためにインデントされていない場合)私はここにあなたのエラーが受胎エラーだと思うモジュールおよびコンポーネントから

+0

あなたの解決方法はどれですか?イベントemiiterまたはSubjectとnext()? – Nitish

+0

私はどちらの方法でもあなたのサービスをシングルトンにする必要があります。 – Sefa

関連する問題