将 angular2 表单指令应用于自定义输入表单元素

Applying angular2 form directives to custom input form elements

我想创建一个自定义 InputCustom 组件并使用它来创建模型驱动表单。

我的自定义组件只是包装了一个输入字段并使用 Bootstrap material design 的外观。

@Component({
 selector:'inputCustom',
 template:`
    <div class="form-group label-floating is-empty">
        <label class="control-label" for="input">Type here</label>
        <input class="form-control" id="input" type="text">
        <p class="help-block">Some help text</p>
        <span class="material-input"></span>
    </div>
`})
class InputCustom{....}

Angular2 中 创建模型驱动表单时

<form [ngFormModel]="formRef">
    <input type ="email" ngControl="email">
</form>

表单元素上的所有 Controls 都已注册到 ControlGroup。通过使用 formRef,您可以跟踪控制器内的字段值。

@Component({...})
class FormController{
    formRef: ControlGroup;
    constructor(...){
        this.form.valueChanges.subscribe(data => console.log('changes',  data));
    }
}

现在,我希望人们像这样使用我的组件

<form [ngFormModel]="formRef">
    <inputCustom type ="email" ngControl="email">
</form>

问题 1:我需要编写自己的自定义 ngControl 指令吗?

问题 2:如何将 ngControl 传播到被 <inputCustom> 包裹的内部 <input> 元素?

Q3:我的Control应该如何在周围的表格ControlGroup中注册?

我看到了两种实现方式:

  • 提供您的控件作为自定义组件的参数

    @Component({
      selector: 'inputCustom',
      template: `
        <input [ngFormControl]="control"/>
      `
    export class FormFieldComponent {
      (...)
      @Input()
      control: Control;
    }
    

    这样您的输入将自动采用父组件中定义的表单的一部分。

  • 实现一个符合 ngModel 的组件。实现起来有点长(您需要在自定义指令中实现并注册 ControlValueAccessor),但这样您就可以直接在自定义指令中直接使用 ngFormControlngModel组件。

    <inputCustom type ="email" [ngFormControl]="email">
    

    有关详细信息,请参阅此问题:

我认为这篇文章可能会让您感兴趣:

我想自定义 ValueAccessor 应该可以。


- https://plnkr.co/edit/Bz7wLC5qq7s6Fph1UwpC?p=preview(DI 提供的值访问器)

    providers: [provide(NG_VALUE_ACCESSOR, {useClass: UIDropdownComp, multi: true})]
})
export class UIDropdownComp implements ControlValueAccessor {

- http://plnkr.co/edit/slVMz6Kgv6KlnUNMDe3o?p=preview(注入组件的 ngControl 和分配的值访问器 "manually"

export class Address implements ControlValueAccessor{
addressForm: ControlGroup;
    value:any;
     addressForm: ControlGroup;
  constructor(@Optional() ngControl: NgControl, elementRef: ElementRef,fb: FormBuilder) {  
    ngControl.valueAccessor = this;

另见 https://github.com/angular/angular/issues/2543

Angular 2 material 实现自定义输入表单元素是了解如何实现 ValueAccessor 的重要信息来源。

因此,只需深入了解此处的源代码并查看输入组件: https://github.com/angular/material2