ControlValueAccessor with multiple formControl in

2020-06-02 10:11发布

I have multiple formcontrols in the child component, how to apply validators in the child component, So that original form will become invalid. It would be ideal to implement it with ControlValueAccessor but want to start with simple @input form group.

@Component({
  selector: 'my-child',
  template: `

  <h1>Child</h1>
  <div [formGroup]="childForm">
    <input formControlName="firstName">
    <input formControlName="lastName">
  </div>
  `
})

export class Child {
  @Input()
  childForm: FormGroup;
}

http://plnkr.co/edit/K1xAak4tlUKtZmOV1CAQ

标签: angular
3条回答
相关推荐>>
2楼-- · 2020-06-02 10:29

What you want to do can be achieved more easily without implementing ControlValueAccessor. Instead, you can simply set the viewProviders in the child component to use the existing parent NgForm as the ControlContainer.

Then, there's no need to pass the form/formGroup as an input parameter to the child component as the form controls will automatically be part of the parent's form.

child.component.ts:

@Component({
    selector: 'child',
    templateUrl: './child.component.html',
    viewProviders: [{ provide: ControlContainer, useExisting: NgForm}]
})
export class Child {
    @Input() firstName;
    @Input() lastName;
}

input-child.component.html:

<h1>Child</h1>
<div>
    <input [(ngModel)]="firstName" name="firstname">
    <input [(ngModel)]="lastName" name="lastname">
</div>

parent.component.html:

<form #personalForm="ngForm" name="personalForm">
    <child [firstName]="firstName" [lastName]="lastName"></child>
</form>
查看更多
对你真心纯属浪费
3楼-- · 2020-06-02 10:37

I don't know why the question was down voted, but I feel it may be helpful to other So I am posting the answer. After multiple attempts to bind child's formgroup I was able to successfully bind value

  @Component({
  selector: 'my-child',
  template: `

  <h1>Child</h1>
  <div [formGroup]="name">
    <input formControlName="firstName">
    <input formControlName="lastName">
  </div>
  `,
  providers: [
    {provide: NG_VALUE_ACCESSOR, useExisting: Child, multi: true}
  ]
})

export class Child implements ControlValueAccessor {
  name: FormGroup;
  constructor(fb: FormBuilder) {
    this.name = fb.group({
      firstName:[''],
      lastName: ['']
    });
  }

  writeValue(value: any) {
    if(value) {
        this.name.setValue(value);
    }
  }

  registerOnChange(fn: (value: any) => void) {
    this.name.valueChanges.subscribe(fn);
  }

  registerOnTouched() {}
}

http://plnkr.co/edit/ldhPf7LTFVtTFHe9zfAj?p=preview

查看更多
▲ chillily
4楼-- · 2020-06-02 10:43

At first, this helped me a lot, but then I found out, that we're over-complicating things. We do not have to build our own formControl, we can just pass the formGroup to our child component. In the parent component, instead of

this.form = fb.group({
  name:['Angular2 (Release Candidate!)'],
  username: [{firstName: 'First', lastName: 'Last'}],
  email:['My Email']  
});

we initialize username as a FormGroup instead of a control:

this.form = fb.group({
  name:['Angular2 (Release Candidate!)'],
  username: fb.group({
   firstName: ['First'],
   lastName: ['Last']
  }),
  email:['My Email']
});

In the child component we need a Input Property for the FormGroup

@Input()
usernameGroup: FormGroup;

In the child template:

<div [formGroup]="usernameGroup">
   <input formControlName="firstName">
   <input formControlName="lastName">
</div>

and then in the parent template:

<my-child [usernameGroup]="form.controls.username"></my-child>

For more information, check out this post: https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2

Building your own formControl is really an overkill here, for more information about that, have a look here: http://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html

查看更多
登录 后发表回答