使用主题/可观察的

时间:2019-05-02 21:06:03

标签: angular observable subject

我正在创建一个应用程序,用户可以在其中将商品添加到购物车中,然后在本地存储中跟踪这些商品。当用户单击一个组件中的“添加”按钮时,我需要导航栏实时更新项目数,但无法使用事件发射器来设置应用程序。

我要寻找的功能很简单,当我添加一个项目并将其放入本地存储时,我的导航栏中购物车徽标旁边的数字应该增加1。我知道可以使用Observables和主题,我只是很难理解它。我将代码从组件移动到服务开始,因为我认为这将允许两个组件与其通信。我可以使用该服务将这些项目正确地添加到本地存储中,但是在那之后我需要跟踪该服务添加的项目数。

这是服务:

@Injectable({
  providedIn: 'root'
})
export class MenuService {
  public apiRoot: string = `http://localhost:3000`;
  orders;

  constructor(private http: HttpClient) { }

  order(id, name, options, price) {
    //confirm the order is correct
    const orderConfirmed = confirm("Add this item to your cart?");

    if (orderConfirmed) {
    let order = new Order(id, name, options, price)   

    //get and set any existing orders from local storage or set to a blank array if there are none
    this.orders = localStorage.getItem('order') ? JSON.parse(localStorage.getItem('order')) : [];

    //push to our orders array
    this.orders.push(order)

    //store in localStorage
    localStorage.setItem('order', JSON.stringify(this.orders)) 
    }
  }

然后是我的navbar.ts:

export class NavbarComponent implements OnInit {
  itemsInCart;
  constructor() { }

  getItemsInCart() {
    this.itemsInCart = JSON.parse(localStorage.getItem('order'))
  }

  ngOnInit() {
    this.getItemsInCart();
  }

}

现在,我只是直接从本地存储中提取项目并显示它们,但是如果我要添加其他项目,显然这将无法实时进行,基本上我想将导航栏组件置于路由器出口可以订阅this.orders中的MenuService属性,这样当用户向购物车中添加商品时,我就可以实时跟踪this.orders的长度。抱歉,如果这似乎很明显,仍在学习!

2 个答案:

答案 0 :(得分:0)

当您关闭浏览器选项卡或刷新数据被破坏时,不要那样在内存中使用本地存储,(专家级别,您应该使用Ngrx Store)

  

检查不相关的组件:与服务here共享数据

storage.service.ts

export class StorageService {
  private foo: String;
  public fooChanged$: EventEmitter<any>; // For Communication between components
  constructor() {
    this.fooChanged$ = new EventEmitter(); // For Communication between components 
  }

  public emitFooChange(): void {// For Communication between components
    this.fooChanged$.emit();
  }

  setFoo(data: String) {
    this.foo = data;
  }

  getFoo(): Number {
    return this.foo;
  }
}

component.ts

constructor(private storageService: StorageService){}
ngOnInit(){
  this.storageService.setFoo("Foo");
  console.log('foo', this.storageService.getFoo());
}

答案 1 :(得分:0)

为您的服务添加一个主题,通过您的订购方法对其进行调用,然后在您的组件中进行订阅

storage.service.ts

orders
ordersChanged = new Subject<any>()

order(){
   //your code
   this.ordersChanged.next(this.orders)
    }

component.ts

itemsInCart

constructor(private storageService: StorageService){}

ngOnInit(){
   this.storageService.ordersChanged.subscribe(items => itemsInCart = items)
}