繁体   English   中英

无法读取角度2中记录编辑表单中未定义的属性

[英]Cannot read property of undefined in record edit form in angular 2

我的编辑表单中存在未定义属性的问题。 我有一个API,可用来创建和更新客户。 问题是某些嵌套属性是可选的,这在创建或编辑已存在的字段时很好,但是当在未使用这些属性创建的客户上编辑其中一个嵌套字段时,我不知道该怎么做字段并不断获取无法读取属性未定义的错误。

这是我的客户对象:

export class Customer { 
  CompanyName: string;
  DisplayName: string;
  FamilyName: string; 
  GivenName: string;
  Id: number;
  Title: string;
  BillAddr: BillAddress;
  ShipAddr: ShipAddress;
  PrimaryPhone:  PrimaryPhoneNumber;
  Mobile: MobileNumber;
  PrimaryEmailAddr: PrimaryEmailAddress;
 }


  export class ShipAddress {
   City: string;
   Country: string;
   CountrySubDivisionCode: string; 
   Line1: string;
   Line2: string; 
   Line3: string; 
   Line4: string; 
   Line5: string; 
   PostalCode:string;
 }

   export class BillAddress {
   City: string;
   Country: string;
   CountrySubDivisionCode: string; 
   Line1: string;
   Line2: string; 
   Line3: string; 
   Line4: string; 
   Line5: string; 
   PostalCode:string;
 }

  export class PrimaryPhoneNumber {
    FreeFormNumber: number;
  }

  export class MobileNumber {
    FreeFormNumber: number;
  }

  export class PrimaryEmailAddress {
    Address: string; 
  }

这是来自edit组件的html:

<h1 class="page-header">Edit Customer</h1>
<div [ngBusy]="busy"></div>
<form (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-md-6">
<h3>Customer information</h3>
<div class="form-group">
    <label for="customertitle">Title</label>
    <input type="text" class="form-control" id="cutomertitle" placeholder="Title" name="title" [(ngModel)]="customer && customer.Title" >
</div>
<div class="form-group">
    <label for="customerGivenName">First Name</label>
    <input type="text" class="form-control" id="customerGivenName" placeholder="First Name" name="givenname" [(ngModel)]="customer && customer.GivenName" >
</div>
<div class="form-group">
    <label for="customerFamilyName">Last Name</label>
    <input type="text" class="form-control" id="customerFamilyName" placeholder="Surname" name="familyname" [(ngModel)]="customer && customer.FamilyName" >
</div>
<div class="form-group">
    <label for="customerEmailAddress">Email Address</label>
    <input type="text" class="form-control" id="customerEmailAddress" placeholder="Email" name="email" [(ngModel)]="customer && customer.PrimaryEmailAddr.Address" >
</div>
<div class="form-group">
    <label for="customerPhone">Phone</label>
    <input type="text" class="form-control" id="customerPhone" placeholder="Phone Number" name="primaryphone" [(ngModel)]="customer && customer.PrimaryPhone.FreeFormNumber" >
</div>
<div class="form-group">
    <label for="customerMobile">Mobile</label>
    <input type="text" class="form-control" id="customerMobile" placeholder="Mobile Number" name="mobile" [(ngModel)]="customer && customer.Mobile.FreeFormNumber" >
</div>
</div>

<div class="col-md-6">
<h3>Address:</h3>
<div class="form-group">
    <label for="customerLine1">Line 1</label>
    <input type="text" class="form-control" id="cutomerLine1" placeholder="Line 1" name="line1" [(ngModel)]="customer && customer.BillAddr.Line1" >
</div>
<div class="form-group">
    <label for="customerLine1">Line 2</label>
    <input type="text" class="form-control" id="cutomerLine2" placeholder="Password" name="line2" [(ngModel)]="customer && customer.BillAddr.Line2" >
</div>
<div class="form-group">
    <label for="customerLine1">Line 3</label>
    <input type="text" class="form-control" id="cutomerLine3" placeholder="Password" name="line3" [(ngModel)]="customer && customer.BillAddr.Line3" >
</div>
<div class="form-group">
    <label for="customerCity">City</label>
    <input type="text" class="form-control" id="customerCity" placeholder="Password" name="city" [(ngModel)]="customer && customer.BillAddr.City" >
</div><div class="form-group">
    <label for="customerLine1">State/Province</label>
    <input type="text" class="form-control" id="cutomerLine1" placeholder="Password" name="Province" [(ngModel)]="customer && customer.BillAddr.CountrySubDivisionCode" >
</div>
<div class="form-group">
    <label for="customerLine1">Postal Code</label>
    <input type="text" class="form-control" id="cutomerLine1" placeholder="Password" name="postcode" [(ngModel)]="customer && customer.BillAddr.PostalCode" >
</div>
</div>
</div>
<button type="submit" class="btn btn-default">Save Changes</button>
</form>

当前的详细信息通过此函数在oninit中获取:

getCustomer(id): void {
    this.busy = this.customersService.getCustomer(id)
          .then(customer => this.customer = customer);

  }

第一个问题是数据将异步传输,因此在所有字段上呈现视图时都将无法undefined customer 第二个问题确实是,由于某些字段没有值,因此也会引发错误。

通常,这可以通过初始化customer来解决:

customer = {};

但是这里的问题仍然是,您有一些更深的属性路径,尽管如此,它们仍然会引发错误,例如: customer.BillAddr.Line3 当然,您可以初始化对象中具有的所有特性,但这对我来说似乎很丑。

所有这些都可以通过安全的导航操作员解决。 不幸的是,双向绑定,即[(ngModel)]不允许安全的导航操作员。

但!

[(ngModel)]="something"等于以下内容:

[ngModel]="something" (ngModelChange)="changeHappened($event)"

单向绑定确实支持安全导航操作员。 因此,您可以做的是使用三元运算符,该运算符捕获用户输入的内容,并将其分配给具有customer.Title = $event变量(在此示例中)。 通过使用三元运算符,您可以消除undefined的错误(如果最初没有值,则将空字符串应用于字段):

[ngModel]="customer?.Title" 
(ngModelChange)="customer?.Title ? customer.Title = $event : ''"

(所有功劳都归功于这个答案: https : //stackoverflow.com/a/36016472/6294072

我也建议在这里使用模型驱动的形式,在该形式中,您可以将所有字段初始设置为空,然后将值设置为具有值的字段并摆脱ngModel。 只是抛出第二种选择。

但总而言之,上述解决方案应该摆脱您的错误! :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM