使用 Subject/Observable 更新购物车中商品的显示
Update display for items in shopping cart with Subject/Observable
我正在创建一个应用程序,用户可以在其中将商品添加到他们的购物车,然后它会在本地存储中跟踪这些商品。当用户单击一个组件中的添加按钮时,我需要导航栏实时更新项目数量,但我无法将事件发射器用于我的应用程序的设置方式。
我正在寻找的功能很简单,当我添加一个项目并将其放入本地存储时,购物车徽标旁边导航栏中的数字应该增加 1。我知道这可以使用Observables 和 Subjects,我只是很难理解它。我已将代码从组件移至服务开始,因为我认为这将允许两个组件与其通信。我可以使用该服务将项目正确添加到本地存储,但之后我就卡住了,我需要跟踪通过该服务添加的项目数量。
这是服务:
@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();
}
}
现在我只是直接从本地存储中提取项目并显示它们,但显然如果我要添加其他项目这将无法实时工作,基本上我想制作我的导航栏组件在 router-outlet 上面能够订阅 MenuService
中的 this.orders
属性 这样我就可以作为用户实时跟踪 this.orders
的长度将商品添加到购物车。抱歉,如果这看起来很明显,仍在学习!
当您关闭浏览器选项卡或刷新数据被破坏时,不要在内存中使用 localstorage 存储,(专家级您应该使用 Ngrx 存储)
check Unrelated Components: Sharing Data with a Service 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());
}
为您的服务添加一个主题,在您的订购方法中调用它并在您的组件中订阅它
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)
}
我希望您使用的是 Angular 框架,那里的服务遵循单例模式,因此 属性 也只有一个实例。 (无需使用可观察模式。)
使用 属性 cart_items_count 创建服务,在构造函数中将值(从本地存储中提取的实际计数)分配给 属性。当您添加到购物车时,cart_items_count 也增加 1。
我正在创建一个应用程序,用户可以在其中将商品添加到他们的购物车,然后它会在本地存储中跟踪这些商品。当用户单击一个组件中的添加按钮时,我需要导航栏实时更新项目数量,但我无法将事件发射器用于我的应用程序的设置方式。
我正在寻找的功能很简单,当我添加一个项目并将其放入本地存储时,购物车徽标旁边导航栏中的数字应该增加 1。我知道这可以使用Observables 和 Subjects,我只是很难理解它。我已将代码从组件移至服务开始,因为我认为这将允许两个组件与其通信。我可以使用该服务将项目正确添加到本地存储,但之后我就卡住了,我需要跟踪通过该服务添加的项目数量。
这是服务:
@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();
}
}
现在我只是直接从本地存储中提取项目并显示它们,但显然如果我要添加其他项目这将无法实时工作,基本上我想制作我的导航栏组件在 router-outlet 上面能够订阅 MenuService
中的 this.orders
属性 这样我就可以作为用户实时跟踪 this.orders
的长度将商品添加到购物车。抱歉,如果这看起来很明显,仍在学习!
当您关闭浏览器选项卡或刷新数据被破坏时,不要在内存中使用 localstorage 存储,(专家级您应该使用 Ngrx 存储)
check Unrelated Components: Sharing Data with a Service 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());
}
为您的服务添加一个主题,在您的订购方法中调用它并在您的组件中订阅它
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)
}
我希望您使用的是 Angular 框架,那里的服务遵循单例模式,因此 属性 也只有一个实例。 (无需使用可观察模式。)
使用 属性 cart_items_count 创建服务,在构造函数中将值(从本地存储中提取的实际计数)分配给 属性。当您添加到购物车时,cart_items_count 也增加 1。