将Angular2反应形式与嵌套的TypeScript模型对象

时间:2016-10-24 19:33:51

标签: angular typescript dynamicform form-control

我正在尝试在我的应用程序中使用角度2模型驱动的表单,但如果我有嵌套对象(具有null值),我无法使其按预期工作。

这是我的代码:

person.model.ts(这是具有地址作为嵌套对象的Person模型对象)

import {Address} from './address.model';
export class Person{
   personId: string;
   name: string
   age: number;
   address: Address;
}

address.model.ts

export class Address{
   addressId: string;
   street: string
   city: string;
   state: string;
   zip: string
}

person.component.ts

@Component( {
selector: 'app-person',
templateUrl: 'person.component.html'
})
export class PersonComponent implements OnInit {
personForm: FormGroup;
person: Person;

constructor( private someService: PersonService, private formBuilder: FormBuilder) {}    

ngOnInit(){
   this.someService.getPersonCall( personId)
      .subscribe ( person => {
           this.person = person;
           this.buildForm();
       }
};

buildForm(): void {
   this.personForm = this.formBuilder.group ({
        'name': [this.person.name, [Validator.required]],
        'age': [this.person.age], 
        'street': [this.person.address.streetOne],
        'city': [this.person.address.streetOne],
        'state': [this.person.address.state],
        'zip': [this.person.address.zip],

    });
    this.registerForChanges();
}

registerForChanges(): void {
    this.personForm.get('name').valueChanges.subscribe(value => this.person.name=value);
    this.personForm.get('age').valueChanges.subscribe(value => this.person.age=value);
    this.personForm.get('street').valueChanges.subscribe(value => this.person.address.streetOne=value);
    this.personForm.get('city').valueChanges.subscribe(value => this.person.address.city=value);
    this.personForm.get('state').valueChanges.subscribe(value => this.person.address.state=value);
    this.personForm.get('zip').valueChanges.subscribe(value => this.person.address.zip=value);
}


onSubmit() {
    this.someService.update(this.person).subscribe( response => 
    this.person = response);
}

这是我的person.component.html

<form *ngIf="person" (ngSubmit)="onSubmit()" [formGroup]="personForm"
          novalidate>
    <div class="col-md-6">
        <div class="form-group">
            <label for="nameId">Name</label>
            <input type="text" class="form-control" formControlName="name" id="nameId"/>    
        </div>
        <div class="form-group">
            <label for="ageId">Age</label>
            <input type="number" class="form-control" formControlName="age" id="ageId"/>    
        </div>
   </div>
   <div class="col-md-6">
        <div class="form-group">
            <label for="streetId">Street</label>
            <input type="text" class="form-control" formControlName="street" id="streetId"/>    
        </div>
        <div class="form-group">
            <label for="cityId">City</label>
            <input type="text" class="form-control" formControlName="city" id="cityId"/>    
        </div>
        <div class="form-group">
            <label for="stateId">State</label>
            <input type="text" class="form-control" formControlName="state" id="stateId"/>    
        </div>
        <div class="form-group">
            <label for="zipId">Zip</label>
            <input type="text" class="form-control" formControlName="zip" id="zipId"/>    
        </div>
   </div>

   <button type="submit" [disabled]="!personForm.valid">Save </button>

</form>

我正在尝试更新从服务调用中填充的person对象,但是当我检索person对象时,person对象在address属性上具有null值,并且它在buildForm函数中破坏了我的代码。

我尝试了其他几种方式,但无法使其正常工作

版本#2

buildForm(): void {
 if ( !this.person.address ) {
    this.personForm = this.formBuilder.group ({
        'name': [this.person.name, [Validator.required]],
        'age': [this.person.age], 
        'street': [''],
        'city': [''],
        'state': [''],
        'zip': [''],

    });
 } else {
     this.personForm = this.formBuilder.group ({
        'name': [this.person.name, [Validator.required]],
        'age': [this.person.age], 
        'street': [this.person.address.streetOne],
        'city': [this.person.address.streetOne],
        'state': [this.person.address.state],
        'zip': [this.person.address.zip],

     });
 }

    this.registerForChanges();
}

通过此更改,我能够无任何错误地呈现表单,但是当我尝试更新任何地址字段时,它在registerForChanges函数中失败。

版本#3

registerForChanges(): void {

if (! person.address) {
    person.address = new Address();    
this.personForm.get('name').valueChanges.subscribe(value => this.person.name=value);
this.personForm.get('age').valueChanges.subscribe(value => this.person.age=value);
this.personForm.get('street').valueChanges.subscribe(value => this.person.address.streetOne=value);
this.personForm.get('city').valueChanges.subscribe(value => this.person.address.city=value);
this.personForm.get('state').valueChanges.subscribe(value => this.person.address.state=value);
this.personForm.get('zip').valueChanges.subscribe(value => this.person.address.zip=value);
}

在此更改后,当我保存表单而不更改地址字段时,我最终将空记录添加到地址表中。

如果函数的address属性不为null,则此代码无效。

有人可以帮助我使这段代码正常工作

plunker link

1 个答案:

答案 0 :(得分:1)

如果我理解你的问题,address是可选的。您想要涵盖两种情况:

  1. 加载表单时没有addressnull},如果没有任何内容添加到addressStreetCityStateZip),您希望在点击保存时保持null

  2. 加载表单时没有addressnull},如果有address个值添加了某些内容(StreetCityStateZip,您要保存这些值

  3. 您可以这样实现 - 在buildForm()函数中,检查this.person.address是否等于null。如果是,则创建新的Address

        buildForm(): void {
    
            if (!this.person.address) {
            this.person.address = new Address();
            }
        }
    

    这可以防止在addressnull时创建表单时出现的错误。下一步是创建一个将在onSubmit()函数中使用的函数,以检查this.person.address值是null还是''(空字符串)。如果是,则该功能会将this.person.address设置为null并且您不会保存空的Address对象,它仍将是null。如果它不是null,它将使用插入的值保存Address对象。让我们调用该函数checkAddress()

    checkAddress(): void {
      if (this.person.address.street == null | this.person.address.street == '' &&
          this.person.address.city == null | this.person.address.city == '' &&
          this.person.address.state == null | this.person.address.state == '' &&
          this.person.address.zip == null | this.person.address.zip == '') {
            this.person.address = null;
          }
    }
    

    最后,您需要在函数checkAddress中调用函数onSubmit()

    onSubmit() {
      console.log('On Save')
      this.checkAddress();
      console.log(this.person);
      console.log(this.person.address);
    }
    

    此处working Plunker

    注意 - 我在下面添加了以下代码&#34; save&#34; onSubmit()函数中的代码可以防止错误,如果您首先单击保存并显示空值,然后尝试插入一些值:

    if (!this.person.address) {
        this.person.address = new Address();
    }
    

    希望这会有所帮助。欢呼声。