组件视图不显示从承诺中解决的数据
Component View not displaying data resolved from a promise
我有一个名为 ProfileComponent 的组件,它使用名为 ProfileService 的服务来检索其数据。 ProfileService 有一个名为 getProfile 的方法,它是 returns 一个承诺。在 then 方法中,我将必要的配置文件数据分配给名为配置文件的组件上的 public 属性。问题是视图似乎没有等待承诺解决以在视图中显示信息。它只是给出一个错误,"property undefined"。我看过使用 Page life Cycle Hooks,但它对解决问题没有帮助。
配置文件组件
import { Component , OnInit } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Profile } from './profile';
import { ProfileService } from './profile.service';
@Component({
selector:'profile',
templateUrl: 'build/profile/profile.component.html',
providers: [ProfileService]
})
export class ProfileComponent{
// public properties
profile: Profile;
constructor(private profileService: ProfileService){
this.getProfile();
}
private getProfile(){
this.profileService.getProfile()
.then(data => {
console.log(data); // I see the needed data here
this.profile = data;
});
}
}
配置文件服务
imports...
@Injectable()
export class ProfileService {
profile: Profile = {
"firstName": 'Chelsea',
"lastName": 'Wilson',
"phone": '713-567-0957',
"email": 'julip@gmail.com',
"authorizationCode":'1232839475234537',
"agreementExpiration": new Date('12/31/2017'),
"ESIID" : '123294734SDFDSSD23'
};
getProfile(){
return Promise.resolve(this.profile);
}
}
个人资料视图
<div class="main-nav-wrapper">
<div class="main-nav-content brite-card">
<h2 class="brite-card-header">Personal Details</h2>
<div class="profile-item">
<span class="profile-label">Name</span>
<span class="profile-detail">{{profile.firstName}} {{profile.lastName}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Email</span>
<span class="profile-detail">{{profile.email}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Phone Number</span>
<span class="profile-detail">{{profile.phone}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Authorization Code</span>
<span class="profile-detail">{{profile.authorizationCode}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Agreement Expiration Date</span>
<span class="profile-detail">{{profile.agreementExpiration}}</span>
</div>
<div class="profile-item">
<span class="profile-label">ESIID</span>
<span class="profile-detail">{{profile.ESIID}}</span>
</div>
</div>
</div>
错误
EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in build/profile/profile.component.html:5:41
ORIGINAL EXCEPTION: TypeError: Cannot read property 'firstName' of null
PS
我有另一个组件和服务可以协同工作,但我使用 *ngFor
来显示它的信息,所以我认为 *ngFor
对另一个有影响。
我认为,您应该在 ngOnInit() 方法中从 ProfileService 获取数据。你需要 import { OnInit } from '@angular/core' and put class 来实现它。 ngOnInit() 方法将在模板制定之前处理(?)。很可能在您的构造函数完成后(Promise 仍未完成)显示模板并且配置文件仍然为空。希望这有帮助。我是 Angular 2 的新手,所以我猜。
您需要为 profile
属性,
创建一个空对象
选项 1:
profile: Profile = new Profile(); // Provided its a class.
选项 2:
如果您可能不实例化配置文件(是一个接口),您可以使用可为空的属性
{{profile.firstName}} -> {{profile?.firstName}}
希望对您有所帮助!!
有更好的方法来处理这种情况。请看this plunker。由于您不知道数据何时准备好,您可以这样做:
用空数据初始化您要在视图中显示的信息(为了防止视图中出现错误)
private profile: Profile = {
"firstName": '',
"lastName": '',
"phone": '',
"email": ',
"authorizationCode":'',
"agreementExpiration": '',
"ESIID" : ''
};
显示加载弹出窗口,以便用户知道正在发生某些事情,并在信息准备好之前禁用视图。
信息准备就绪后,关闭弹出窗口以便用户可以与视图交互。
尽管使用可空变量可能有效,但您始终需要从用户的角度考虑问题,以及如何让他们更容易理解事情。我不会乐意使用首先向我显示空视图然后几秒钟后(并且没有让我知道任何信息)视图更改并显示信息的应用程序。
我有一个名为 ProfileComponent 的组件,它使用名为 ProfileService 的服务来检索其数据。 ProfileService 有一个名为 getProfile 的方法,它是 returns 一个承诺。在 then 方法中,我将必要的配置文件数据分配给名为配置文件的组件上的 public 属性。问题是视图似乎没有等待承诺解决以在视图中显示信息。它只是给出一个错误,"property undefined"。我看过使用 Page life Cycle Hooks,但它对解决问题没有帮助。
配置文件组件
import { Component , OnInit } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Profile } from './profile';
import { ProfileService } from './profile.service';
@Component({
selector:'profile',
templateUrl: 'build/profile/profile.component.html',
providers: [ProfileService]
})
export class ProfileComponent{
// public properties
profile: Profile;
constructor(private profileService: ProfileService){
this.getProfile();
}
private getProfile(){
this.profileService.getProfile()
.then(data => {
console.log(data); // I see the needed data here
this.profile = data;
});
}
}
配置文件服务
imports...
@Injectable()
export class ProfileService {
profile: Profile = {
"firstName": 'Chelsea',
"lastName": 'Wilson',
"phone": '713-567-0957',
"email": 'julip@gmail.com',
"authorizationCode":'1232839475234537',
"agreementExpiration": new Date('12/31/2017'),
"ESIID" : '123294734SDFDSSD23'
};
getProfile(){
return Promise.resolve(this.profile);
}
}
个人资料视图
<div class="main-nav-wrapper">
<div class="main-nav-content brite-card">
<h2 class="brite-card-header">Personal Details</h2>
<div class="profile-item">
<span class="profile-label">Name</span>
<span class="profile-detail">{{profile.firstName}} {{profile.lastName}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Email</span>
<span class="profile-detail">{{profile.email}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Phone Number</span>
<span class="profile-detail">{{profile.phone}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Authorization Code</span>
<span class="profile-detail">{{profile.authorizationCode}}</span>
</div>
<div class="profile-item">
<span class="profile-label">Agreement Expiration Date</span>
<span class="profile-detail">{{profile.agreementExpiration}}</span>
</div>
<div class="profile-item">
<span class="profile-label">ESIID</span>
<span class="profile-detail">{{profile.ESIID}}</span>
</div>
</div>
</div>
错误
EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in build/profile/profile.component.html:5:41
ORIGINAL EXCEPTION: TypeError: Cannot read property 'firstName' of null
PS
我有另一个组件和服务可以协同工作,但我使用 *ngFor
来显示它的信息,所以我认为 *ngFor
对另一个有影响。
我认为,您应该在 ngOnInit() 方法中从 ProfileService 获取数据。你需要 import { OnInit } from '@angular/core' and put class 来实现它。 ngOnInit() 方法将在模板制定之前处理(?)。很可能在您的构造函数完成后(Promise 仍未完成)显示模板并且配置文件仍然为空。希望这有帮助。我是 Angular 2 的新手,所以我猜。
您需要为 profile
属性,
选项 1:
profile: Profile = new Profile(); // Provided its a class.
选项 2: 如果您可能不实例化配置文件(是一个接口),您可以使用可为空的属性
{{profile.firstName}} -> {{profile?.firstName}}
希望对您有所帮助!!
有更好的方法来处理这种情况。请看this plunker。由于您不知道数据何时准备好,您可以这样做:
用空数据初始化您要在视图中显示的信息(为了防止视图中出现错误)
private profile: Profile = { "firstName": '', "lastName": '', "phone": '', "email": ', "authorizationCode":'', "agreementExpiration": '', "ESIID" : '' };
显示加载弹出窗口,以便用户知道正在发生某些事情,并在信息准备好之前禁用视图。
信息准备就绪后,关闭弹出窗口以便用户可以与视图交互。
尽管使用可空变量可能有效,但您始终需要从用户的角度考虑问题,以及如何让他们更容易理解事情。我不会乐意使用首先向我显示空视图然后几秒钟后(并且没有让我知道任何信息)视图更改并显示信息的应用程序。