【发布时间】:2019-10-05 13:21:22
【问题描述】:
我有一个 Angular 应用程序,它应该在 API 调用服务器后显示一组组件,服务器将响应用户可以根据他/她的个人资料访问的组件。
我使用一个单独的服务来处理和检索用户组件,并将其存储在服务本身中以便在 webapp 中轻松获取。
我的实现如下,
进行 API 调用的 API 服务,
api.service.ts
import { Injectable } from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import {AuthService} from './auth.service';
import {Params} from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class ApisService {
GET_BATCH_SCHEDULE = 'http://localhost:8000/getbatchplan';
GET_USER_STATIONS = 'http://localhost:7071/api/getUserStations';
GET_USER_LOCATIONS = 'http://localhost:7071/api/getUserLocations';
constructor(private httpClient: HttpClient, private authService: AuthService) { }
getCutplanBatches() {
return this.httpClient.get(this.GET_BATCH_SCHEDULE);
}
getStations(location: string) {
if (location === undefined){
console.log("undefined location call");
location = 'aqua';
}
const params = new HttpParams()
.set('email', this.authService.getAuthenticateduserInfo().displayableId)
.append('location', location);
return this.httpClient.get(this.GET_USER_STATIONS, { params: params });
}
getLocations() {
const params = new HttpParams()
.set('email', this.authService.getAuthenticateduserInfo().displayableId);
return this.httpClient.get(this.GET_USER_LOCATIONS, { params: params });
}
}
单独的服务来检索和存储与组件相关的信息
station.service.ts
import {Injectable} from '@angular/core';
import {ApisService} from './apis.service';
import {StationModel} from '../models/station.model';
import {BehaviorSubject, Observable} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class StationService {
userStations: BehaviorSubject<StationModel[]>;
userLocation: string;
constructor(private apiService: ApisService) {
this.userStations = new BehaviorSubject<StationModel[]>([]);
this.setLocationStations('aqua');
}
setLocation(location: string) {
this.userLocation = location;
}
getLocation() {
return this.userLocation;
}
setLocationStations(locationSelect: string) {
this.apiService.getStations(locationSelect).subscribe((data: StationModel[]) => {
this.userStations.next(data['stations']);
console.log('setting user locations:', this.userStations);
return this.userStations;
});
}
public getLocationStations(): Observable<StationModel[]> {
console.log('inside station service:', this.userStations);
console.log('inside station service loc:', this.userLocation);
return this.userStations.asObservable();
}
}
和一个解析器根据路由将必要的信息传递给组件。 在这里,它调用 station.service.ts 以获取存储的值并使用 api.service.ts 进行必要的 API 调用
station.resolver.service.ts
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs';
import {StationService} from '../../services/station.service';
import {Injectable} from '@angular/core';
import {StationModel} from '../../models/station.model';
@Injectable({
providedIn: 'root'
})
export class StationRouteResolver implements Resolve<StationModel> {
currentStation: StationModel;
constructor(private stationService: StationService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
console.log('Resolves:', route.params['location']);
if (this.stationService.getLocation() === undefined) {
console.log('Initial setting:', route.params['location']);
this.stationService.setLocation(route.params['location']);
}else if (this.stationService.getLocation() !== route.params['location']) {
console.log('Changing location settings:', route.params['location']);
this.stationService.setLocation(route.params['location']);
}else{
console.log('Same location found!');
}
this.stationService.getLocationStations().subscribe((stations: StationModel[]) => {
console.log('observer resolver:', stations);
this.currentStation = stations.filter((station) => {
return station.stationPath === route.params['station'];
})[0];
console.log('----current station:', this.currentStation);
});
return this.currentStation;
// this.currentStation = this.stationService.getLocationStations().filter((station) => {
// return station.stationPath === route.params['station'];
//
// })[0];
}
}
站组件是使用来自服务的输入来处理要显示的组件。
station.component.ts
import {Component, Input, OnInit} from '@angular/core';
import {StationModel} from '../../models/station.model';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-station',
templateUrl: './station.component.html',
styleUrls: ['./station.component.scss']
})
export class StationComponent implements OnInit {
station: StationModel;
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.route.data.subscribe((data) => {
this.station = data['station'];
});
console.log('*****params station', this.route.data['station']);
}
}
在模板中使用 *ngIf 来选择正确的组件
station.component.html
<app-batch-list-view *ngIf="station.stationType == 'o'"></app-batch-list-view>
<app-dashboard-view *ngIf="station.stationType == 'm'"></app-dashboard-view>
<app-print-view *ngIf="station.stationType == 'p'"></app-print-view>
问题是我在启动和刷新页面时遇到变量未定义错误,特别是在 station.component 中,因为 station.stationType 未定义,应用程序从此中断。
但是,如果我导航返回并返回相同的路线,这可行(使用 ngif 加载组件时没有任何错误)。
我想知道这是因为使用了解析器还是我的实现有问题?
对不起,如果我的问题不是很清楚。如果有人能指出哪里出了问题,那将非常有帮助。
【问题讨论】:
-
尝试在组件模板中将这些
station.stationType更改为station?.stationType。 angular.io/guide/… -
哇,解决了!
-
但根本原因可能是什么?是因为异步方法吗?
-
是不是因为异步方法,是的。这是一个常见问题。
标签: javascript angular typescript angular-ui-router