离子3 - 数据加载后ngModel未定义

时间:2018-02-01 17:33:52

标签: javascript angular ionic3

我是角度4的初学者...在过去的几个月中试图搜索这么多次,但没有结果,尽管这似乎是最简单的事情。

这是一个离子应用程序。用户登录后,整个用户对象将保存到localStorage。尝试过几个插件,但是很简单:

window.localStorage.setItem('User', JSON.stringify(user));

用户对象结构:

export class User {
constructor(
    public token?: string,
    public user_email?: string,
    public email?: string,
    public first_name?: string,
    public last_name?: string,
    public user_roles?: {
        ID?: number,
        caps?: {
            administrator?: boolean,
        },
        roles?: object,
    },
    public id?: number,
    public device_feedback?: boolean,
    public role?: string,
    public username?: string,
    public billing?: Address,
    public shipping?: Address
) {}
}

export class Address {
    first_name?: string;
    last_name?: string;
    company?: string;
    address_1?: string;
    address_2?: string;
    city?: string;
    state?: string;
    postcode?: string;
    country?: string;
    email?: string;
    phone?: number   
}

settings.ts:(我添加了ngOnInit和this.platform.ready(){},因为思想数据还没有准备就绪......)

export class Settings implements OnInit{
 [other vars]

 user: User;

 constructor(public storage: Storage, private platform: Platform) { }

ngOnInit() {
    // this.storage.ready().then(() => {
    // this.storage.get("User").then((data) => {
    this.platform.ready().then(() => {
        let data = window.localStorage.getItem('User');
        if (data) {
            this.user = JSON.parse(data);
            this.email = this.user.user_email;
            console.log('user', this.user);
            console.log('this.user.user_email', this.user.user_email);

        }
    });
}

Settings.html

<ion-content>
<ion-list padding>
    <ion-list-header>
        Title
    </ion-list-header>
    <ion-item>
        <ion-label color="primary" fixed>Email</ion-label>
        <ion-input class="in" type="email" [(ngModel)]="user.user_email" disabled="true"></ion-input>
    </ion-item>

user_email显示在console.log中,引用为 this.user.user_email ,同一属性在HTML中出错...这怎么可能?在浏览器或设备中相同:http://prntscr.com/i8rfhg 我也尝试了user: any,但得到了相同的结果......

如何?为什么?我错过了什么?

这是离子信息:

@ionic/cli-utils  : 1.19.1
ionic (Ionic CLI) : 3.19.1

全球套餐:

cordova (Cordova CLI) : 7.1.0

本地包裹:

@ionic/app-scripts : 1.3.0
Cordova Platforms  : none
Ionic Framework    : ionic-angular 3.0.1

系统:

Android SDK Tools : 25.2.5
Node              : v6.11.0
npm               : 5.6.0

非常感谢!

4 个答案:

答案 0 :(得分:1)

您正在尝试访问用户对象的属性user_email,而该用户对象在初始化之前为null /。

尝试:

user: User = {}; // initial value

或者:

<ion-list padding *ngIf="user">
    <ion-list-header>
        Title
    </ion-list-header>
    <ion-item>
        <ion-label color="primary" fixed>Email</ion-label>
        <ion-input class="in" type="email" [(ngModel)]="user.user_email" disabled="true"></ion-input>
    </ion-item>

答案 1 :(得分:1)

In ngOnInit, the callback for this.platform.ready() is executed asynchronously. Before that, user is undefined and [(ngModel)]="user.user_email" causes an error.

You can prevent that error with the safe navigation operator. Since it works only for one-way data binding, you should split [(ngModel)] in its two parts, [ngModel] and (ngModelChange). In addition to that change, you can keep the input element disabled until user is initialized, to prevent entering data that will be lost anyway.

[ngModel]="user?.user_email" (ngModelChange)="setUserEmail($event)" [disabled]="!user"

with the component method:

setUserEmail(value: string): void {
  if (this.user) {
    this.user.user_email = value;
  }
}

The code is illustrated in this stackblitz, where the user object is initialized after a few seconds.

答案 2 :(得分:1)

you don't have instance of User in this.user.

export class User {
    public token: string;
    public user_email: string;
    public email: string;
    public first_name: string;
    public last_name: string;
    public user_roles : Object = {
        ID: null,
        caps: {
            administrator: false,
        },
        roles: {},
    };
    public id: number;
    public device_feedback: boolean;
    public role: string;
    public username: string;
    public billing: Address;
    public shipping: Address;

    public set(data:any){
        if(!data){
            return;
        }
        this.token = data.token;
        this.user_email = data.user_email;
        this.email = data.email;
        this.first_name = data.first_name;
        this.last_name = data.last_name;
        this.id = data.id;
        this.device_feedback = data.device_feedback;
        this.role = data.role;
        this.username = data.username;
        this.billing = data.billing;
        this.shipping = data.shipping;

        this.user_roles = data.user_roles;

    } }

and

export class Settings implements OnInit{  [other vars]

 user: User = new User(); constructor(public storage: Storage, private platform: Platform) { }

ngOnInit() {
    // this.storage.ready().then(() => {
    // this.storage.get("User").then((data) => {
    this.platform.ready().then(() => {
        this.user.set(window.localStorage.getItem('User'));

    });
}

答案 3 :(得分:0)

我使用导出接口和类。

export interface UserCaps
        administrator: boolean;
}

export interface UserRole {
        ID: null;
        caps: UserCaps;
        roles: any;
}

export interface Address {
    first_name?: string;
    last_name?: string;
    company?: string;
    address_1?: string;
    address_2?: string;
    city?: string;
    state?: string;
    postcode?: string;
    country?: string;
    email?: string;
    phone?: number   
}

export interface User {public token: string;
    user_email: string;
    email: string;
    first_name: string;
    last_name: string;
    user_roles : UserRole;
    id: number;
    device_feedback: boolean;
    role: string;
    username: string;
    billing: Address;
    shipping: Address;
}

export class User {}

然后我使用新的Class()初始化用户

user = new User();