3

我正在尝试在我的应用程序中使用 angular 2 模型驱动表单,但如果我有嵌套对象(具有空值),我将无法使其按需要工作。

这是我的代码:

person.model.ts(这是 Person 模型对象,地址为嵌套对象)

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

地址.model.ts

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

人.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>

我正在尝试更新从服务调用中填充的人员对象,但是当我检索人员对象时,人员对象的地址属性为空值,并且它破坏了我在 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);
}

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

如果函数的地址属性不为空,则此代码可以正常工作。

有人可以帮我使这段代码工作吗

插件链接

4

1 回答 1

1

如果我很好地理解了您的问题,address则为可选。您要涵盖两种情况:

  1. 加载表单时没有address(it's null) 并且如果没有向address值 ( Street、或) 添加任何内容City,您希望在单击Save时保留它StateZipnull

  2. 加载表单时没有address(it's null) 并且如果将某些内容添加到address值 ( Street,或City,您想要保存这些值StateZip

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

    buildForm(): void {

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

这将防止在创建表单时出现的错误addressis null。下一步是创建一个函数,该函数将在onSubmit()函数中用于检查this.person.address值是否仍然是null''(空字符串)。如果是,则该函数将设置this.person.addressnull并且您不会保存空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);
}

这是工作的 Plunker

注意 - 我在函数中的“保存”代码下方添加了以下代码,onSubmit()以防止如果您首先单击保存为空值然后尝试插入一些值时出现错误:

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

希望这可以帮助。干杯。

于 2016-10-25T16:57:19.343 回答