参考Global Events in Angular 2我正在尝试实施购物车服务,该服务会在将新商品添加到购物车时发出活动。我在另一个名为navbar的组件(不是购物车的孩子)中订阅了这个服务活动,在那里我展示了我的购物车数量等。
我的购物车服务:
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;
}
...
...
}
但是,每当我添加项目时,导航栏中都不会发生任何事情,即alert(id)
或onItemAdded()
不会自动调用,以便cartItemCount等可以自动更新。
出了什么问题?
答案 0 :(得分:1)
您应该仅将add(int, Vertex<Integer>)
用于EventEmitter
!
对于您的场景,完全符合@Output()
..
创建Observable
并致电Subject
,它类似于next()
。
emit()
订阅部分应该没问题。
答案 1 :(得分:1)
我认为你的错误是一个概念错误。
正如@mxii所说,你的情况完全适合Observable
行为,你不应该使用promise和事件发射器(在你的项目实际添加到服务器端之前调用)。
如果你想用承诺修复你的问题,我认为解决方案是在你得到答案后触发事件:
return this.http.get( this.myUrl + 'add' + '/' + id + '/', { withCredentials:true})
.toPromise()
.then(response => {
this.cart.push(response.json());
this.itemAdded$.emit(id);
});
然后在您的顶级模块(通常是AppModule
)中提供它,以确保您的应用程序中只有一个实例。
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);
}
...
...
}
答案 2 :(得分:0)
服务是每个提供商的单身。您正在向导航栏注入CartService
的不同实例,并且正在调用addToCart
函数。
我希望应用程序的每个页面都显示Navbar
,因此以下是CartService
全局单例的方法。
@NgModule({
declarations: [
],
imports: [
],
providers: [CartService], //<--- added here
bootstrap: [AppComponent]
})
export class AppModule { }
从模块和组件中删除任何其他providers: [CartService]
(如果您没有缩进以创建其他实例)