Angular 2+将指令传递给自定义组件

时间:2018-01-04 10:21:35

标签: angular angular-directive angular-components

我创建了一个自定义组件,它具有它&#39;拥有@input()@output等等。该组件有一个<input />字段,用户可以在其中输入一些值。

例如:<my-component ...></my-component>

我在我的HTML中引用它并且它完美无缺。我还创建了几个指令,通过简单的regexp验证表单输入数据。我可以在像以下形式的普通输入中使用它们:

<input type="text" validator1 validator2 validator3 />

有没有办法将一个或多个这些指令(但也没有一个)传递给我的自定义组件而不在组件的源代码中对它们进行硬编码?

某种...params要评估?

提前感谢您的所有帮助

瓦莱里奥

1 个答案:

答案 0 :(得分:3)

你正在寻找的模式绝对是可能的,但在你想要的某种意义上,指令是无法实现的。这是因为Angular是编译的,这意味着你不能“硬编码”一个指令(至少没有做出不建议在生产中做的奇怪的东西) )。

您的组件可以接受名为validators的输入,该输入应该是一个函数数组(或类的实例,如果需要),然后使用它来验证。

例如,您可以使用以下三个超简单验证器:

export const required   = value => value != null && value != ''
export const minLength3 = value => value == null || value.length > 3
export const maxLength9 = value => value == null || value.length < 9

您的my-component接受这些验证器的数组。为简单起见,验证器实际上是字符串的谓词。换句话说,它是一个与上述三个函数具有相同签名的函数:(value: string) => boolean。我们将此输入初始化为空数组,有效地将其作为默认值,以防万一没有传递给它。

@Input() validators: ((value: string) => boolean)[] = []

在使用者组件的模板(使用my-component的组件)中,我们现在通过向其传递一系列验证器来使用该组件。

<my-component [validators]="[required, maxLength9]"></my-component>

当然,要使用它们,我们必须要么DI它们,要么只是将它们实例化为组件类的成员。要将它与DI一起使用,验证器必须是类(至少版本为5.x.x及以下版本)。

import {required, maxLength9} from '../validators'
export class ConsumerComponent {
  public required = requierd
  public maxLength9 = maxLength9
}

my-component组件当然应该使用这些验证器。例如,可以在每个changeinputblur事件上运行以下函数,具体取决于您希望何时运行验证程序。

public validate(value: string): boolean {
  let valid: boolean = true
  this.validators.forEach(validator => {
    const result = validator(value)
    valid = valid || result
  })
}

您现在可以更好地动态控制要在该字段上运行的验证程序。当然,您也可以在应用程序的运行时动态更改这些。这需要付出以下代价:没有未使用的验证器。 Angular编译器无法再确定您使用的验证器,这意味着所有验证器都必须在应用程序的最终捆绑中导入,即使其中一些可能永远不会被使用。

您可能对Angular中的反应形式感兴趣。您可以阅读reactive forms in official documentation,或查看Todd Motto's article on reactive forms in AngularReactive Forms in Angular by Pascal Precht on thoughtram