Я создаю приложение, в котором пользователь добавляет товар в свою корзину, а затем он отслеживает эти элементы в локальном хранилище. Когда пользователь нажимает кнопку добавления в одном компоненте, мне нужно, чтобы панель навигации обновлялась с количеством элементов в режиме реального времени, но я не могу использовать эмиттер событий с тем, как настроено мое приложение.
Функциональность, которую я ищу, проста: когда я добавляю элемент и он попадает в локальное хранилище, число на моей панели навигации рядом с логотипом корзины покупок должно увеличиваться на 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();
}
}
Прямо сейчас я просто извлекаю элементы непосредственно из локального хранилища и отображаю их, но, очевидно, это не будет работать в режиме реального времени, если я добавлю другие элементы, в основном я хочу сделать свой компонент навигационной панели, который находится над выходом маршрутизатора. чтобы иметь возможность подписаться на свойство this.orders в MenuService, чтобы я мог отслеживать длину this.orders в режиме реального времени, когда пользователь добавляет товары в корзину. Извините, если это кажется очевидным, все еще учусь!





вместо этого не используйте хранилище localstorage в памяти, когда вы закрываете вкладку браузера или данные обновления уничтожаются (уровень эксперта вы должны использовать Ngrx Store)
check Unrelated Components: Sharing Data with a Service here
хранилище.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;
}
}
компонент.ts
constructor(private storageService: StorageService){}
ngOnInit(){
this.storageService.setFoo("Foo");
console.info('foo', this.storageService.getFoo());
}
Добавьте тему в свою службу, вызовите ее в методе заказа и подпишитесь на нее в своем компоненте.
хранилище.service.ts
orders
ordersChanged = new Subject<any>()
order(){
//your code
this.ordersChanged.next(this.orders)
}
компонент.ts
itemsInCart
constructor(private storageService: StorageService){}
ngOnInit(){
this.storageService.ordersChanged.subscribe(items => itemsInCart = items)
}
Я надеюсь, что вы используете фреймворк Angular, сервисы следуют шаблону singleton, поэтому будет только один экземпляр этого свойства. (Нет необходимости использовать наблюдаемый шаблон.)
Создайте сервис со свойством cart_items_count. В конструкторе присвойте значение (реальное количество, извлеченное из локального хранилища) свойству. Когда вы добавляете в корзину, увеличьте cart_items_count также на 1.
Это было идеально, это помогло мне лучше понять предметы после того, как я немного повозился с ним, и я также смог убедиться, что цена обновляется, подписавшись на тот же предмет в другом компоненте, очень полезно. Большое спасибо @RadekF!