我可以订阅非http数据吗?

时间:2017-06-09 15:46:13

标签: angular observable

我正在制作购物车,我想让购物车图标显示购物车中的商品数量。

目前我还没有为购物车设置API,因为它不是优先考虑的事项。所以,就目前而言,我只有一个服务,其中包含一系列项目,每次点击“添加到购物车”时都会添加一个项目。

我的问题是,当我向购物车添加内容时,菜单栏中的图标和计数不会更新。

如何在不使用http服务的情况下实现这一目标?

模拟购物车服务

@Injectable()
export class ShoppingcartService {
    //MOCK SERVICE

//fields
items: any[] = [];



//constructor
constructor() { }

//public methods

addToShoppingcart(item: any) {
     this.items.push(item);
}

removeFromShoppingcart() {

}

changeQuantity() {

}

getAllItems() {
    return this.items;
}

getItemsCount() {
    return this.items.length;

}

购物车图标TS

export class ShoppingcartIconComponent implements OnInit {
count: number;


constructor(private shoppingcartService: ShoppingcartService) {
    this.count = this.shoppingcartService.getItemsCount();
}

ngOnInit() {

}

}

购物车图标Html

    <div class="btn btn-outline-info cart">
  <i class="fa fa-shopping-cart">

  </i>
  <div class="count">
    {{count}}
  </div>
</div>

添加到购物车的组件是..

HTML

  <button class="btn btn-warning" (click)="addToCart()">
    <i class="fa fa-plus-square"></i> {{shoppingCartTitle}}
  </button>

TS

   export class AlbumdetailsComponent implements OnInit {
    shoppingcart;

    album: any[];
    id: number;

    shoppingCartTitle: string = "Add to shoppingcart";

    constructor(private musicService: MusicService,
           private activatedRoute: ActivatedRoute,
            private shoppingcartService: ShoppingcartService) 
       {
            this.shoppingcart = this.shoppingcartService.getAllItems();
        }
    ngOnInit() {
//

    }

}

    addToCart() {
        this.shoppingcartService.addToShoppingcart(this.album);
    }

}

情况的快速截图,Json显示购物车中确实存在一个项目,但计数器保持为0。 组件不是彼此的父或子,一个在菜单中,另一个在主视图中。 enter image description here

1 个答案:

答案 0 :(得分:3)

是的,你可以。只需使用Observable.of()

返回这些项目的可观察项

以下是您可以修改的几种方法:

addToShoppingcart(item: any) {
     this.items.push(item);
     return Observable.of({message:'Item Added', addedItem: item})
     //note that object can be anything you want to mock
}


removeFromShoppingcart() {
  return Observable.of({message:'Item Deleted'});
}

changeQuantity() {
}

getAllItems() {
    return Observable.of(this.items); //this automatically wraps the array in an observable
}

getItemsCount() {
    return Observable.of(this.items.length); //this returns a number, but is wrapped in an observable

}

其余的代码可以像对待通常那样对待它们中的每个代码,即订阅它们。例如,在构造函数中,您可以执行以下操作:

constructor(private shoppingcartService: ShoppingcartService) {
    this.shoppingcartService.getItemsCount()
        .subscribe(count=>this.count = count);
}

注意:要使用Observable.of,请记住导入它:

import "rxjs/add/observable/of";

编辑:

我保留上述服务代码以供参考,因为他们回答了问题标题。

如果您希望每次致电items[]时异步更新addToShoppingCart(),则需要创建SubjectBehaviourSubject来跟踪它。在下面的示例中,我们将使用BehaviourSubject,因为它允许初始化默认值。

在您的服务中,创建一个名为itemBSubject的属性,其类型为BehaviourSubject。不要将此与items[]混淆。这个主题是跟踪您的items[]

items: any[] = [];
itemBSubject: BehaviourSubject<any[]>

在您的构造函数中,将itemBSubjectitems同步:

constructor() {
   this.itemBSubject = new BehaviorSubject<any[]>(items); 
}

现在,在修改items[]每个方法中,您还需要使用itemBSubject更新.next()

addToShoppingcart(item: any) {
     this.items.push(item);
     this.itemBSubject.next(this.items); // this will update the behavior subject
     return this.itemBSubject.asObservables();

}

//same goes to delete. call .next() after this items are sliced.

现在这里是所有人的魔力。对于getItems()getItemsCount(),请返回BehaviourSubject(作为可观察对象)。

getItems(){
    return this.itemBSubject.asObservable()
}

getItemsCount(){
   return this.itemBSubject.asObservable()
    .map(items=>items.length)
}

现在,即使您在另一个组件中添加项目,您也会意识到count会自动增加。