【发布时间】:2020-03-12 12:10:51
【问题描述】:
我正在开发一个 Angular 应用程序作为业余项目,并尝试使用最佳实践编写干净的代码。
我创建了一个“.loader”css 类并将其放在 app-component 的主 div 上。我的目的是在 BackendService.loading 字段为 true 时附加此类,并在 false 时分离。这将为整个页面创建加载效果。我计划在调用端点时将此 BackendService.loading 更改为 true,并在提供响应时更改为 false。我创建了这个 BackendService 来处理所有其他服务的 http 调用。这样我就不必在每个订阅的响应回调的每个组件中都设置这个变量了。
问题:当一个新的 api 调用请求到来时,我可以从 BackendService 设置变量,但是当它结束时我不能再次将它设置为 false,因为它的订阅是在组件控制器中完成的。
如何在提供响应时将 BackendService 中的加载变量设置为 false? (我读了太多关于 Observable 的东西,并试图将 http.get 的返回值包装在另一个 observable 中,但它们都不起作用)或者我需要实现其他更干净的东西吗?
后端服务:
export class BackendService {
apiUrl = 'http://localhost:8080';
loading = false;
token = null;
constructor(private http: HttpClient) {}
getOptions() {
return {
headers: new HttpHeaders()
.set('Authorization', this.token)
.set('Content-type', 'application/json')
.set('Access-Control-Allow-Origin', '*')
};
}
getRequest(path: string): Observable<any> {
return this.http.get(this.apiUrl + path, this.getOptions());
}
postRequest(path: string, body: Object): Observable<any> {
return this.http.post(this.apiUrl + path, body, this.getOptions());
}
}
随机使用BackendService进行api调用的其他服务:
export class StudentService {
constructor(private backendService: BackendService) {}
updateLevel(studentId: number) {
return this.backendService.getRequest(
'/student/update-level/' + studentId + '/6/turkce/paragraf');
}
getSummary(studentId: number) {
return this.backendService.getRequest(
'/student/summary/' + studentId) as Observable<StudentSummaryModel>;
}
}
组件控制器内部的 api 调用:(这里我必须在结果回调中注入 BackendService.loading)
export class QuizStartComponent implements OnInit {
constructor(private router: Router,
private quizService: QuizService,
private studentService: StudentService,
private userService: UserService) { }
ngOnInit() {
}
quizStart(quizSize: number) {
this.quizService.quizSize = quizSize;
this.studentService.updateLevel(this.userService.user.id).subscribe(
res => {
this.router.navigate(['/student/question']);
}, err => {
});
}
}
不相关,但这些是 app.component.ts 和 loader css 类:
<app-navigation></app-navigation>
<div class="container mb-auto" [ngClass]="{'loading': backendService.loading}">
<div class="mt-3">
<router-outlet></router-outlet>
</div>
</div>
<app-footer></app-footer>
.loading {
... some css
}
.loading:after {
... some css
}
【问题讨论】:
-
它通常是一个 bool 标志和微调组件上的 *ngIf 的问题。
-
实际上,这里的问题是如何以及在何处设置单个布尔标志。我们是否需要为每次调用设置它,或者我们是否可以使其更通用以保持代码清洁。 @Antoniossss
-
在每个明确意图的代码中添加 1 行代码对我来说似乎很清楚。
标签: angular typescript redux-observable