对于自定义表单组件,是否可以使用 DefaultValueAccessor 而不是 ControlValueAccessor?

gjv*_*lya 7 angular

我需要能够formControlName为我的自定义组件使用该指令。

我一直在阅读有关ControlValueAccessor为子组件实现的多个 SO 问题,这一切似乎都非常脆弱。

许多示例都将<div><span>元素转换为表单元素,因此实现ControlValueAccessor.

但是,我的组件只是使用本机<input>元素。我正在创建一个单独的组件,因为我想在输入中使用一些图标,而且我显然不想在任何地方复制/粘贴图标 css。

我遇到了一个DefaultValueAccessor类,它似乎是 angular 用于所有本机输入元素的类。我是否也可以为我的自定义组件以某种方式利用这种行为?

我只是不想复制这个功能。就错误和各种浏览器行为而言,长期维护它可能很困难。我宁愿只使用已经与本机输入相关联的功能。

编辑

这是<jg-search>(我的自定义组件)的代码片段:

<div>
    <svg>
        <!-- some content -->
    </svg>
    <label for="search">Search</label>
    <input id="search" type="text"></input>
    <svg>
        <!-- some content -->
    </svg>
</div>
Run Code Online (Sandbox Code Playgroud)

我希望能够以一种形式这样称呼它:<jg-search formControlName="keyword">.

这可以通过ControlValueAccessor在 SearchComponent 中实现来实现。但由于我只是使用本机<input type="text">,我不想重新实现DefaultValueAccessor.

yur*_*zui 6

一种可能的解决方案是ngDefaultControl在您的自定义组件上使用属性:

<div [formGroup]="form">
    <jg-search formControlName="x" ngDefaultControl></jg-search>
                                   ^^^^^^^^^^^^^^^^
</div>
Run Code Online (Sandbox Code Playgroud)

现在您需要做的就是将您的input元素与现有的 FormControl链接,如下所示:

@Component({
  selector: 'jg-search',
  template: `
   <input [formControl]="ngControl.control">
  `
})
export class MyInput {
  constructor(public ngControl: NgControl) {}
}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅Ng-run 示例