Creating a custom component wrapping an input control on Angular for reactive forms

我的梦境 提交于 2021-02-11 18:16:12

问题


I'm trying to create a custom component with an input form control inside but I have no idea how to connect the directive formControl and formControlName to the inner input, this is my code:

<div class="input-group">
    <input class="form-control form-control-sm"
        #code />
    <div class="input-group-append">
        <button type="button" class="btn btn-sm btn-success"
            (click)="search()">
            <i class="fa fa-search"></i>
        </button>
    </div>
</div>

this is the .ts file

import { Input, Component, forwardRef, OnInit, ViewChild } from '@angular/core';
import { DefaultValueAccessor, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
    selector: 'search-input',
    templateUrl: './search-input.component.html',
    styleUrls: ['./search-input.component.scss'],
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => SearchInputComponent),
            multi: true
        }
    ]
})
export class SearchInputComponent implements OnInit, ControlValueAccessor {
    writeValue(obj: any) {
    }

    registerOnChange(fn: any) {
    //this.valueAccesor.registerOnChange(fn);
    }

   registerOnTouched(fn: any) {
    //this.valueAccesor.registerOnTouched(fn);
   }

    setDisabledState(isDisabled: boolean) {
    //this.valueAccesor.setDisabledState(isDisabled);
    }
}

It should

<search-input formControlName="code">

Or

<search-input formControl="code">

Please, help me with this, I don't have much experience with Angular


回答1:


In order to have a child component work with the same parent form, you should pass in the Parent Form instance as an input to the child component. The parent form will use the form builder to create the child form control. The child will define the template for the control.

Here is a parent form (Sandbox) with a child component (AppTestInputForm):

import { Component, OnInit } from '@angular/core';
import { FormBuilder, Form, FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-sandbox',
  templateUrl: './sandbox.component.html',
  styleUrls: ['./sandbox.component.css']
})
export class SandboxComponent implements OnInit {
  form: FormGroup;

  constructor(private formBuilder: FormBuilder) { 
    this.form = formBuilder.group({
      searchValue: new FormControl('')
    });
  }
  ngOnInit() {

  }

  submit() {
    if(this.form.valid) {
      console.log(this.form.get('searchValue').value, 'submitting search value');
    }
  }

}
<form [formGroup]="form" (ngSubmit)="submit()">
    <app-test-input-form [parentForm]="form"></app-test-input-form>
    <button type="submit" class="btn btn-primary">Submit</button>
 </form>

Here is the child component which contains the search input:

import { Component, OnInit, Input } from '@angular/core';
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-test-input-form',
  templateUrl: './test-input-form.component.html',
  styleUrls: ['./test-input-form.component.css']
})
export class TestInputFormComponent implements OnInit {
  @Input() parentForm: FormGroup;

  constructor(private formBuilder: FormBuilder) { 

  }

  ngOnInit() {

  }

  search() {
    console.log('searching with value', this.parentForm.get('searchValue').value);
  }
}
<div class="input-group" [formGroup]="parentForm">
  <input class="form-control form-control-sm" formControlName="searchValue" />
  <div class="input-group-append">
    <button type="button" class="btn btn-sm btn-success" (click)="search()">
            <i class="fa fa-search"></i>
        </button>
  </div>
</div>


来源:https://stackoverflow.com/questions/60200533/creating-a-custom-component-wrapping-an-input-control-on-angular-for-reactive-fo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!