Я работаю над написанием компонента, предназначенного для упрощения / унификации внешнего вида и взаимодействия наших форм.Код выглядит примерно так:
Пример использования
...
<my-form-input labelKey = "email" controlName="emailAddress" [form]="userForm">
<input myInput class="form-control" type="email" formControlName="emailAddress" />
</my-form-input>
...
Вы можете видеть, что "emailAddress"
передается MyFormInputComponent
как controlName
и передается во второй раз директиве FormControlName
элемента <input>
.Я хотел бы пропустить это только один раз, чтобы мой конечный пользователь не должен был это делать.
Есть ли хороший способ, которым я могу это сделать, или это просто ограничение, которое я должен принять (еслида, объяснение, почему существует это ограничение, будет приветствоваться)?Код показан ниже.
Я пробовал два подхода:
- Установка аннотации
@HostBinding("attr.formControlName")
в компоненте MyInput
.Я могу манипулировать атрибутом с именем formcontrolname
на элементе таким образом, но он не вызывает директиву, необходимую Angular Forms для правильной регистрации элемента управления в группе. - Попросите пользователя указать
formControlName
к элементу <input>
и считайте его значение для остальной части компонента.Это может сработать, но мне придется обращаться к DOM напрямую через ElementRef
, , что не рекомендуется .Рекомендуемый маршрут для взаимодействия с DOM - Renderer
- , по-видимому, не дает возможности читать атрибуты либо .
my-form-input.component.ts
@Component({
selector: 'my-form-input',
templateUrl: './my-form-input.component.html',
styleUrls: ['./my-form-input.component.scss']
})
export class MyFormInputComponent implements OnInit, AfterContentInit {
@Input()
labelKey: string;
@Input()
controlName: string;
@Input()
form: FormGroup;
@ContentChild(MyInputDirective)
input: MyInputDirective;
ngAfterContentInit(): void {
this.initInput();
}
/**
* Updates the input we project into the template
*/
private initInput() {
this.input.updatePlaceholder(this.labelKey);
// I'd like to somehow edit the FormControlName directive applied to the input here
}
}
my-form-input.component.html
<label>{{ labelKey | translate }}</label>
<ng-content></ng-content>
<my-input-error [control]="form.controls[controlName]" [name]="labelKey | translate" />
my-input.directive.ts
@Directive({
selector: '[myInput]'
})
export class myInputDirective implements OnInit {
private placeholderKey = "";
@HostBinding("placeholder")
private placeholder: string;
updatePlaceholder(placeholderKey: string) {
this.placeholderKey = placeholderKey;
this.placeholder = this.translateService.instant(this.placeholderKey);
}
constructor(private translateService: TranslateService) {
}
}
my-form-error.component.ts
// Not shown since not relevant.