2016-09-16 55 views
0

我只是用TypeScript和Angular2弄湿我的脚。我正在使用具有嵌套对象结构的API。我希望我的模型能够从API中镜像资源。该模型/资源,“查询”,如打字稿定义:Angular2 FormBuilder和嵌套的对象属性返回undefined

// inquiry.ts 
export class Inquiry { 
    name: { 
    first: string, 
    last: string 
    }; 
    email: string; 
    phone: string; 
    question: string; 
} 

我的表单组件是这样的:

import { Component, OnInit } from '@angular/core'; 
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; 
import { InquireService } from './inquire.service'; 
import { Inquiry } from './inquiry'; 

@Component({ 
    selector: 'inquire-form', 
    templateUrl: './inquire-form.component.html' 
}) 
export class InquireFormComponent implements OnInit { 
    inquiryForm: FormGroup; 
    inquiry = new Inquiry; 

    constructor(
    private formBuilder: FormBuilder, 
    private inquireService: InquireService) {} 

    ngOnInit(): void { 
    this.buildForm(); 
    } 

    buildForm(): void { 
    this.inquiryForm = this.formBuilder.group({ 
     'firstName': [ 
     this.inquiry.name.first, [ 
      Validators.required, 
      Validators.minLength(2), 
      Validators.maxLength(50) 
     ] 
     ], ... 
    } 
} 

我得到时,我打我的路线错误是:

Error: Uncaught (in promise): TypeError: Cannot read property 'first' of undefined 

当我登录this.inquiry.name确实undefined,但我不明白为什么。我究竟做错了什么?

+1

你只是说明了'name'属性的类型签名是什么,但实际上并没有初始化zed它。 –

+0

嗯。当我创建新的查询实例(在构造函数之上)时,它没有初始化吗? – Brandon

+0

据我所知,你只是宣称一个Inquiry对象包含4个属性,一个名字为'{first:string,last:string}'和'email','phone'和'question'字符串类型。没有一个属性被明确地初始化,所以它们只有它们的默认值('undefined')。 –

回答

2

问题是您的Inquiry对象上的任何属性都未初始化,因此它们都是默认值undefined。由于name不重新初始化,尝试访问其任何属性(firstlast)将失败。

将它设置在一个构造函数:

constructor() { 
    this.name = {} as any; // too lazy to give first/last properties 
} 

或在声明中初始化:

class Inquiry { 
    name = {} as { 
     first: string, 
     last: string 
    }; 
    email: string; 
    phone: string; 
    question: string; 
} 

,或者如果你想明确地保留类型的声明,而不是依靠类型推断:

class Inquiry { 
    name: { 
     first: string, 
     last: string 
    } = {} as any; 
    email: string; 
    phone: string; 
    question: string; 
} 
+0

啊。第二个例子更有意义。只要我回到我的电脑,我会尽力尝试。非常感谢你的帮助。 – Brandon

+0

我实现了第二个例子,并且我的formBuilder再次运行。谢谢!显然我需要刷上我的TypeScript。 – Brandon

+0

我不会说这是一个打字稿,只是一般的面向对象。这里的区别是你描述的是一个对象的模式,而不是给它一个明确的名字。您将变量/属性声明为具有某些属性的对象。但是您仍然需要像Java或C#中那样初始化该变量以获得某个值。 –