Angular库存筛选组件选择选项后需点击两次才能获取正确数据
问题原因
- 核心为异步代码执行顺序问题:
this.service.getArticles()返回的是异步Observable对象,subscribe的回调函数只会在后端接口响应成功后才会执行,而你写在subscribe外层的console.log(this.articles)会在接口请求发起后立即执行,此时请求还未返回,this.articles还未被赋值更新,打印的是上一次的旧值。
第一次点击Select按钮时,先打印旧的空数组,之后接口才返回数据完成this.articles的赋值,你感知不到后续的赋值操作,误以为第一次点击无效;第二次点击时打印的是第一次请求更新后的值,所以看起来需要点击两次才能生效。 - 额外隐患:每次触发接口请求都会新增一个订阅,没有做销毁处理,长期运行会存在内存泄漏风险。
解决方法
将所有需要依赖接口返回结果的逻辑(包括日志打印、后续业务处理)都移到subscribe的回调函数内,同时补充订阅销毁逻辑避免内存泄漏,修改后的代码如下:
import { Subscription } from 'rxjs'; export class StockStatusComponent implements OnInit, OnDestroy{ articles: Article[] = []; selectedLevel: any; // 统一管理所有订阅 private subscriptions = new Subscription(); constructor(private service: ArticleService) { } ngOnInit(): void { this.dataBackend(); } ngOnDestroy(): void { // 组件销毁时取消所有订阅,避免内存泄漏 this.subscriptions.unsubscribe(); } dataBackend() { const dataSub = this.service.getArticles().subscribe(res => { // 用filter简化原有的循环筛选逻辑 this.articles = res.filter(item => item.stockActual < item.stockMinimo); // 接口返回后再打印最新值 console.log(this.articles); }) this.subscriptions.add(dataSub); } filterByLevels(event: any) { this.selectedLevel = event.target.value; } selectLevel() { console.log("Selected level: " + this.selectedLevel); if (this.selectedLevel === "all") { const levelSub = this.service.getArticles().subscribe(res => { this.articles = res; // 接口返回后再打印最新值 console.log(this.articles); }) this.subscriptions.add(levelSub); } } }
修改后点击一次即可拿到最新的全量商品数据,渲染也会同步更新。
内容的提问来源于stack exchange,提问作者Justanuser2020
相关产品推荐
相关产品推荐

