Angular页面重载时数据丢失问题排查求助
问题根源分析
你的问题核心在于HTTP请求的异步特性,你的myservice.ts里的getcompanylist()写法存在逻辑漏洞:
当你调用this.http.get(...).subscribe(...)时,HTTP请求是异步执行的——代码不会等待服务器返回结果,而是直接继续执行后面的return this.datas,这时候this.datas还没被订阅回调赋值,仍然是初始的undefined。
为什么点击按钮时看起来正常?大概率是因为点击按钮时,之前页面加载时发起的请求已经完成,this.datas已经被赋值,这时候再调用getCompanylist(),返回的是已经有值的this.datas,但这只是巧合,并不是正确的逻辑。
解决方案
我们需要正确处理异步请求,下面提供几种可行的修改方案:
方案1:让Service返回Observable,组件订阅处理
修改myservice.ts
把方法改成直接返回HTTP请求的Observable,不要在Service里存储datas:
import { Observable } from 'rxjs'; // ... getcompanylist(): Observable<any> { alert("service method called"); return this.http.get("http://localhost:8080/tabletolist"); }
修改Company-list.component.ts
在组件里订阅这个Observable,拿到数据后再赋值给datas:
public getCompanylist(){ console.log("getCompanyList() called"); this.newservice.getcompanylist().subscribe((data) => { this.datas = data; console.log(this.datas); console.log("getcomapnylist() in companylistcomponent.ts Called da"); }); };
这样无论是页面加载还是点击按钮,都会发起请求并在数据返回后正确赋值datas。
方案2:使用Async/Await(基于Promise)
如果你更习惯同步风格的代码,可以把Observable转成Promise:
修改myservice.ts
import { lastValueFrom } from 'rxjs'; // ... async getcompanylist() { alert("service method called"); const response = await lastValueFrom(this.http.get("http://localhost:8080/tabletolist")); return response; }
修改Company-list.component.ts
用async/await等待请求完成:
public async getCompanylist(){ console.log("getCompanyList() called"); this.datas = await this.newservice.getcompanylist(); console.log(this.datas); console.log("getcomapnylist() in companylistcomponent.ts Called da"); };
方案3:使用Angular的Async管道(推荐)
这种方式不需要手动订阅,Angular会自动处理订阅和取消订阅,还能避免内存泄漏:
修改Company-list.component.ts
把datas改成Observable类型,直接赋值为Service返回的Observable:
import { Observable } from 'rxjs'; // ... datas$: Observable<any>; ngOnInit() { console.log("NG oninit called.") this.datas$ = this.newservice.getcompanylist(); } public getCompanylist(){ console.log("getCompanyList() called"); this.datas$ = this.newservice.getcompanylist(); };
修改Company-list.component.html
用async管道订阅Observable:
<tbody> <tr align="center" *ngFor="let data of datas$ | async"> <td>{{data.cmpid}}</td> <td>{{data.cmpname}}</td> <td>{{data.cmpproduct}}</td> <td>{{data.cmpqty}}</td> <td>{{data.cmpprice}}</td> </tr> </tbody>
额外建议
- 尽量不要在Service里存储组件需要的数据,Service的职责应该是封装数据请求逻辑,把数据返回给组件处理。
- 使用Async管道是Angular里处理异步数据的最佳实践之一,能减少手动订阅的代码,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Arjun
相关产品推荐
相关产品推荐

