如何从许多ngModel更改之一中检测到更改

时间:2019-11-19 10:46:10

标签: angular angular8

我开始使用Angular并遇到以下问题:

对于.ts文件,我有一个像这样的对象:

{
  person: {
    a1: {
      name: x
      age: 19
    },
    b1: {
      name: y
      age: 19
    },
    c1: {
      name: z
      age: 19
    }
   ....
}

detechChange() { //any changes come here }

想象一下我在对象人身上有很多财产

在HTML部分中,我有一些输入可以绑定对象人的数据

// this one can not iterate
<input [(ngModel)]="person.a1.name"></input>
<input [(ngModel)]="person.a1.age"></input>
<input [(ngModel)]="person.b1.name"></input>
<input [(ngModel)]="person.b1.age"></input>
<input [(ngModel)]="person.c1.name"></input>
<input [(ngModel)]="person.c1.name"></input>

在这些输入之一发生更改时,是否有任何方法可以检测到更改?我知道该事件(ngModelChange),但是我必须将其绑定到每个输入,反正还有可能更聪明?

5 个答案:

答案 0 :(得分:1)

尝试这样:

Working Demo

.html

<input type="text" [(ngModel)]="person.a1.name" (ngModelChange)="detectChange('a1', 'name', $event)"/>

.ts

 detectChange(parentKey:string,childKey:string, value:string) {
   console.log(`${parentKey} -> ${childKey}  is ${value}` )
 }

答案 1 :(得分:1)

要使用一种通用方法来检测formFields中发生的更改,可以使用 valueChanges Observable。为此,您需要一个反应式表单。

this.personForm = this.formBuilder.group({
  person1Name: ['', [ Validators.required ]],
  person1Age: ['', [ Validators.required ]]
}); 

this.personForm.valueChanges.subscribe(
  updatedObject => {
    console.log(updatedObject);
  }
); 

答案 2 :(得分:1)

我认为,实现此目标的最佳方法是使用Reactive Forms,因为您要管理大量输入并使用FrameLayout来容纳它们并不是很可扩展。使用反应式表单,您可以定义表单的形状并将其绑定到ngModel上,当用户更改表单或以编程方式更改表单时,屏幕会自动更新。{p>

例如,您需要:

使用“ FormBuilder”创建一个FormGroup

FormGroup

在html

form;
constructor(private fb: FormBuilder) {
}

ngOnInit() {
  form = this.fb.group({
     name: ['', [Validators.Required]],
     age: ['', [Validators.Required]]
  })
}

要获取其价值:

<form [formGroup]="form">
   <input formControlName="name"></input>
   <input formControlName="age"></input>
</form>

要听变化:

this.form.value;

当然,您可以在此处选择完全符合您要求的答案,这可能会解决您的问题,但是看起来干净不太好。

答案 3 :(得分:1)

使用反应性表单,您可以订阅表单的valueChange方法以侦听表单中的更新值

组件

export class AppComponent {
  form: FormGroup;

  constructor() {
    let formBuilder = new FormBuilder();
    this.form = formBuilder.group({
      persons: formBuilder.array([formBuilder.group({
        age: 12,
        name: "Test"
      }), formBuilder.group({
        age: 12,
        name: "Test 123"
      })])
    });

    this.form.valueChanges
      .map((value) => {
        console.log(value);    //Log form changes
        return value;
      })
      .subscribe((value) => {
        console.log(JSON.stringify(value));
      });
  }
}

HTML

<form [formGroup]="form">
    <div formArrayName="persons" *ngFor="let item of form.get('persons').controls;let i = index;">
        <div [formGroupName]="i">
            <input formControlName="name" placeholder="Item name">
</div>
        </div>
</form>

答案 4 :(得分:0)

您有一堆反应式的答案,我也建议使用:)但是这是ngModel的解决方案。您可以使用angular提供的keyvalue管道来避免长时间写所有这些输入。也就是说,如果您的对象是按您提供的那样构建的。因此,您可以执行以下操作:

values = {
  person: {
    a1: {
      name: "x",
      age: 19
    },
    b1: {
      name: "y",
      age: 19
    },
    c1: {
      name: "z",
      age: 19
    }
  }
};

detectChange(key, prop) {
  console.log(`object key: ${key} and property: ${prop}`)
}

,然后是HTML:

<div *ngFor="let val of values?.person | keyvalue">
  <input [(ngModel)]="val.value.name" (ngModelChange)="detectChange(val.key, 'name')"/>
  <input [(ngModel)]="val.value.age"  (ngModelChange)="detectChange(val.key, 'age')"/>
</div>

STACKBLITZ