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

6
我创建了一个自定义组件,它有自己的@input()@output等。该组件有一个<input />字段,用户可以在其中输入一些值。
例如:<my-component ...></my-component> 我在我的HTML中引用它,并且它可以无误地工作。我还创建了几个指令,通过简单的正则表达式验证表单输入数据。我可以在表单中使用它们,就像这样的普通输入框: <input type="text" validator1 validator2 validator3 /> 是否有一种方法可以将其中一个或多个这些指令(也可以没有)传递给我的自定义组件,而不是在组件源代码中硬编码?
有一种类似于...params的方式来评估吗?
非常感谢您的帮助。
Valerio
1个回答

5
您要查找的模式肯定是可能的,但不能通过指令来实现您想要的意义。这是因为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” 组件当然应该使用这些验证器。例如,可以在每个 “change”、 “input” 或 “blur” 事件上运行以下函数,具体取决于您想何时运行验证器。
public validate(value: string): boolean {
  let valid: boolean = true
  this.validators.forEach(validator => {
    const result = validator(value)
    valid = valid || result
  })
}

现在你可以更好地动态控制想要在字段上运行的验证器。当然,在应用程序运行时也可以动态更改这些内容。但是,这样做会带来以下代价:无法摇树(tree-shaking)未使用的验证器。Angular编译器无法确定您正在使用哪些验证器,这意味着所有验证器都必须被导入到您的应用程序的最终捆绑包中,即使其中一些可能永远不会被使用。

您可能会对Angular中的响应式表单感兴趣。您可以阅读官方文档中的响应式表单, 或查看Todd Motto在Angular中的响应式表单文章, 或Pascal Precht在thoughtram上的Angular响应式表单


太棒了。我需要进行一些修改,使其更通用,但这绝对是我正在寻找的解决方案。 - Valerio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接