我做了一个Angular Service,它保留了其他组件可以向其中添加和检索的项目列表。由于某种原因,没有任何内容添加到列表中。它仅在我的服务的add()函数中起作用,但变量不会在其外部被更改。例如,在add()函数末尾,控制台将返回添加的项。但是,当我再次从getItems()函数列表中检查列表时,该列表为空。为什么在推送后list不会在函数之外得到更新?
export class BasketService {
private list: Item[] = [];
constructor() {}
add(product: Product, units: number): void {
let item: Item = new Item();
item.product = product;
item.units = units;
this.list.push(item);
console.log(this.list[(this.list.length - 1)]);
// Log shows item object
}
getItems(): Observable<Item[]> {
console.log(this.list);
// Log shows empty array
return of(this.list);
}
}
编辑
getItems()确实有一个订阅者,但是问题似乎并不出在那儿,因为它接收到一个空的Item数组,即控制台在getItems(在basketService中)打印的相同的空列表。>
export class BasketComponent implements OnInit {
items: Item[];
constructor(private basketService: BasketService) {}
ngOnInit() {
this.getItems();
console.log(this.items.length);
}
getItems(): void {
this.basketService.getItems()
.subscribe(items => {
this.items = items; });
}
答案 0 :(得分:1)
您的getItems()
方法返回一个Observable
,其中包含您的项目列表。您需要订阅该Observable
才能获得这些物品。
此外,每次修改列表时,您都可以使用BehaviorSubject
将列表推入Observable
中。
这样,当添加项目时,您的服务使用者将通过可观察对象得到通知。
@Injectable()
export class BasketService {
private list: Item[] = [];
private subject = new BehaviorSubject<Item[]>([]);
private list$ = this.subject.asObservable();
add(product: Product, units: number): void {
let item: Item = new Item();
item.product = product;
item.units = units;
this.list.push(item);
this.subject.next(this.list); // push the modified list to notify observers
}
getItems(): Observable<Item[]> {
return this.list$;
}
}
像这样使用它:
export class MyComponent implements OnInit {
constructor(private service: BasketService) { }
ngOnInit() {
this.service.getItems().subscribe(items => {
console.log('list modified', items); // this is executed after each list.push()
});
}
}
您还可以将scan
与Subject
一起使用,并摆脱list
变量。该列表将由scan
运算符通过附加到先前的值来创建:
@Injectable()
export class BasketService {
private subject = new Subject<Item>();
private list$ = this.subject.pipe(
scan((list, item) => [...list, item], [] as Item[]),
);
add(product: Product, units: number): void {
let item: Item = new Item();
item.product = product;
item.units = units;
this.subject.next(item);
}
getItems(): Observable<Item[]> {
return this.list$;
}
}
这里是使用扫描运算符的简短Stackblitz demo。
答案 1 :(得分:0)
请确保您的服务使用@Injectable装饰并正确提供,以便使用该服务的所有组件 具有相同的服务实例。