从 HTTP 请求获取数据到模板的后期
Getting data from HTTP request to late in the template
我有一个为主题和行为主题创建 http 请求的服务。然后我将数据从服务获取到 page.ts(在构造函数上)以在模板中显示它。
我做的代码运行良好,但问题是模板 "yelling" 来自主题的数据尚未到达。所以如果我想用它来初始化 FORM 控件或显示数组中的数据,它会给我错误。
PS: 我尝试将主题设置为 behaviorSubject,我遇到了同样的问题。 :(
我确定我在做一个概念错误。
有人知道如何在显示模板之前获取数据吗?
感谢您的帮助
带有主题和行为主题的服务代码:
const INTI_DATA = [];
@Injectable({
providedIn: 'root'
})
export class FormStorageService {
dbSubject = new Subject<any[]>();
dbBSubject = new BehaviorSubject(INTI_DATA);
data$: Observable<any> = this.dbBSubject.asObservable();
private _URL: any = '../assets/DB-Test/data.json';
private dbData: any[] = [];
constructor(private http: HttpClient) {}
getDBDataBehavior() {
this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
const value = response['DB_DATA'];
this.dbBSubject.next(value);
}, error => {
console.log('Error : ', error);
alert(error.message);
});
}
getDBData() {
this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
const value = response['DB_DATA'];
this.dbSubject.next(value);
}, error => {
console.log('Error : ', error);
alert(error.message);
});
}
}
Page.TS (Form2Page) with Subject call
export class Form2Page implements OnInit, OnDestroy {
obsSubscription: Subscription;
public dbData: DataModel[] = [];
itemsForm: FormGroup;
constructor(private storageService: FormStorageService) {
// Get data from DB
this.storageService.getDBData();
this.obsSubscription = this.storageService.dbSubject.subscribe(
(value: any[]) => {
this.dbData = value;
console.log('Value in FORM2 : ', value);
console.log('DB Data in FORM2 in subscribe : ', this.dbData);
},
error => {
console.log('erreur', error);
}
);
console.log('DB Data DB Data in FORM2 : ', this.dbData);
}
ngOnInit() {
console.log('DB Data in FORM2 in ngOnInit : ', this.dbData);
}
ngOnDestroy() {
this.obsSubscription.unsubscribe();
}
}
控制台结果过一会可以看到dbData得到了一些数据
DB Data DB Data in FORM2 : []
form2.page.ts:46 DB Data in FORM2 in ngOnInit : []
form2.page.ts:29 Value in FORM2 : {ITEMS: Array(1)}
form2.page.ts:30 DB Data in FORM2 in subscribe : {ITEMS: Array(1)}
Page.TS (Form3Page) 调用 BehaviorSubject
export class Form3Page implements OnInit {
obsBSubject$ = this.formStorage.data$;
public dbData: any[] = [];
constructor(private formStorage: FormStorageService) {
this.formStorage.getDBDataBehavior();
this.obsBSubject$.subscribe(
(value: any[]) => {
this.dbData = value;
console.log('Value in FORM3 : ', value);
console.log('DB Data in FORM3 in subscribe : ', this.dbData);
},
error => {
console.log('erreur', error);
}
);
console.log('DB Data in FORM3 : ', this.dbData);
}
ngOnInit() {
console.log('DB Data in FORM3 in ngOnInit : ', this.dbData);
}
}
控制台结果过一会可以看到dbData得到了一些数据
Value in FORM3 : []
form3.page.ts:19 DB Data in FORM3 in subscribe : []
form3.page.ts:25 DB Data in FORM3 : []
form3.page.ts:30 DB Data in FORM3 in ngOnInit : []
form3.page.ts:18 Value in FORM3 : {ITEMS: Array(1)}
form3.page.ts:19 DB Data in FORM3 in subscribe : {ITEMS: Array(1)}
您可以使用 *ngIf 来验证数据是否已经到达前端
*ngIf=="data"
您还可以使用另一个 div 和 *ngIf 检查长度是否大于零,以告知数据已经到达此处但没有记录...
首先你必须在 ngOninit 中而不是在构造函数中调用服务方法来获取数据
看看这个 link [
然后在将所有数据显示到模板之前,您必须使用 *ngIf
确保数据已经存在
如果您不关心性能,请使用 setTimeOut 函数解决解决方案,但我个人不喜欢这个解决方案...
我注意到您的代码和逻辑中存在一些问题。
ngOnInit
通常用于所有initialization/declaration。最好避免将逻辑放在构造函数中。构造函数应该只用于初始化 class 成员而不应该做实际的 "work"。所以我建议您将逻辑从构造函数移至 ngOnInit()
您没有在控制台中看到数据,因为流程是异步的。因此,您的日志会在 this.dbdata
实际收到值之前显示在控制台中。
由于第 2 点中提到的原因,如果您尝试在与控制台相同的行上创建表单,您将收到错误消息,因为没有数据。相反,您应该在订阅方法中收到数据后创建表单。
Page.TS (Form3Page) 调用 BehaviorSubject
export class Form3Page implements OnInit {
obsBSubject$ = this.formStorage.data$;
public dbData: any[] = [];
constructor(
private formStorage: FormStorageService
) { }
ngOnInit() {
this.formStorage.getDBDataBehavior();
this.obsBSubject$.subscribe(
(value: any[]) => {
this.dbData = value;
this.createForm();
...
},
error => {
console.log('erreur', error);
}
);
}
createForm() {
// Create form here
}
}
我有一个为主题和行为主题创建 http 请求的服务。然后我将数据从服务获取到 page.ts(在构造函数上)以在模板中显示它。
我做的代码运行良好,但问题是模板 "yelling" 来自主题的数据尚未到达。所以如果我想用它来初始化 FORM 控件或显示数组中的数据,它会给我错误。
PS: 我尝试将主题设置为 behaviorSubject,我遇到了同样的问题。 :( 我确定我在做一个概念错误。
有人知道如何在显示模板之前获取数据吗?
感谢您的帮助
带有主题和行为主题的服务代码:
const INTI_DATA = [];
@Injectable({
providedIn: 'root'
})
export class FormStorageService {
dbSubject = new Subject<any[]>();
dbBSubject = new BehaviorSubject(INTI_DATA);
data$: Observable<any> = this.dbBSubject.asObservable();
private _URL: any = '../assets/DB-Test/data.json';
private dbData: any[] = [];
constructor(private http: HttpClient) {}
getDBDataBehavior() {
this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
const value = response['DB_DATA'];
this.dbBSubject.next(value);
}, error => {
console.log('Error : ', error);
alert(error.message);
});
}
getDBData() {
this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
const value = response['DB_DATA'];
this.dbSubject.next(value);
}, error => {
console.log('Error : ', error);
alert(error.message);
});
}
}
Page.TS (Form2Page) with Subject call
export class Form2Page implements OnInit, OnDestroy {
obsSubscription: Subscription;
public dbData: DataModel[] = [];
itemsForm: FormGroup;
constructor(private storageService: FormStorageService) {
// Get data from DB
this.storageService.getDBData();
this.obsSubscription = this.storageService.dbSubject.subscribe(
(value: any[]) => {
this.dbData = value;
console.log('Value in FORM2 : ', value);
console.log('DB Data in FORM2 in subscribe : ', this.dbData);
},
error => {
console.log('erreur', error);
}
);
console.log('DB Data DB Data in FORM2 : ', this.dbData);
}
ngOnInit() {
console.log('DB Data in FORM2 in ngOnInit : ', this.dbData);
}
ngOnDestroy() {
this.obsSubscription.unsubscribe();
}
}
控制台结果过一会可以看到dbData得到了一些数据
DB Data DB Data in FORM2 : []
form2.page.ts:46 DB Data in FORM2 in ngOnInit : []
form2.page.ts:29 Value in FORM2 : {ITEMS: Array(1)}
form2.page.ts:30 DB Data in FORM2 in subscribe : {ITEMS: Array(1)}
Page.TS (Form3Page) 调用 BehaviorSubject
export class Form3Page implements OnInit {
obsBSubject$ = this.formStorage.data$;
public dbData: any[] = [];
constructor(private formStorage: FormStorageService) {
this.formStorage.getDBDataBehavior();
this.obsBSubject$.subscribe(
(value: any[]) => {
this.dbData = value;
console.log('Value in FORM3 : ', value);
console.log('DB Data in FORM3 in subscribe : ', this.dbData);
},
error => {
console.log('erreur', error);
}
);
console.log('DB Data in FORM3 : ', this.dbData);
}
ngOnInit() {
console.log('DB Data in FORM3 in ngOnInit : ', this.dbData);
}
}
控制台结果过一会可以看到dbData得到了一些数据
Value in FORM3 : []
form3.page.ts:19 DB Data in FORM3 in subscribe : []
form3.page.ts:25 DB Data in FORM3 : []
form3.page.ts:30 DB Data in FORM3 in ngOnInit : []
form3.page.ts:18 Value in FORM3 : {ITEMS: Array(1)}
form3.page.ts:19 DB Data in FORM3 in subscribe : {ITEMS: Array(1)}
您可以使用 *ngIf 来验证数据是否已经到达前端
*ngIf=="data"
您还可以使用另一个 div 和 *ngIf 检查长度是否大于零,以告知数据已经到达此处但没有记录...
首先你必须在 ngOninit 中而不是在构造函数中调用服务方法来获取数据
看看这个 link [
然后在将所有数据显示到模板之前,您必须使用 *ngIf
确保数据已经存在如果您不关心性能,请使用 setTimeOut 函数解决解决方案,但我个人不喜欢这个解决方案...
我注意到您的代码和逻辑中存在一些问题。
ngOnInit
通常用于所有initialization/declaration。最好避免将逻辑放在构造函数中。构造函数应该只用于初始化 class 成员而不应该做实际的 "work"。所以我建议您将逻辑从构造函数移至ngOnInit()
您没有在控制台中看到数据,因为流程是异步的。因此,您的日志会在
this.dbdata
实际收到值之前显示在控制台中。由于第 2 点中提到的原因,如果您尝试在与控制台相同的行上创建表单,您将收到错误消息,因为没有数据。相反,您应该在订阅方法中收到数据后创建表单。
Page.TS (Form3Page) 调用 BehaviorSubject
export class Form3Page implements OnInit {
obsBSubject$ = this.formStorage.data$;
public dbData: any[] = [];
constructor(
private formStorage: FormStorageService
) { }
ngOnInit() {
this.formStorage.getDBDataBehavior();
this.obsBSubject$.subscribe(
(value: any[]) => {
this.dbData = value;
this.createForm();
...
},
error => {
console.log('erreur', error);
}
);
}
createForm() {
// Create form here
}
}