Angular 2+ 向自定义组件传递指令
Angular 2+ pass directives to a custom component
我创建了一个自定义组件,它有自己的 @input()
、@output
等等。该组件有一个 <input />
字段,用户可以在其中输入一些值。
例如:<my-component ...></my-component>
我在我的 html 中引用了它,它完美地工作。我还创建了几个指令,通过简单的正则表达式验证表单输入数据。我可以在如下形式的纯输入中使用它们:
<input type="text" validator1 validator2 validator3 />
有没有一种方法可以将这些指令中的一个或多个(还有 none 个指令)传递到我的自定义组件,而无需在组件的源代码中对它们进行硬编码?
某种...params
要评估?
在此先感谢您的帮助
瓦莱里奥
您正在寻找的模式绝对是可能的,但在您尝试的某种意义上无法通过指令实现。这是因为 Angular 是 编译的 ,这意味着你不能 not "hard-code" 一个指令(至少不能没有做不建议在生产中做的奇怪事情)。
你的组件可以接受一个名为 validators
的输入,它应该是一个函数数组(或者 class 的实例,如果你需要的话),然后用它来验证。
例如,您可以拥有以下三个超级简单的验证器:
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 或简单地将它们实例化为组件的成员 class。要将它与 DI 一起使用,验证器必须是 classes(至少就 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 中的 响应式表单感兴趣。您可以阅读 reactive forms in official documentation, or take a look at Todd Motto's article on reactive forms in Angular, or Reactive Forms in Angular by Pascal Precht on thoughtram.
我创建了一个自定义组件,它有自己的 @input()
、@output
等等。该组件有一个 <input />
字段,用户可以在其中输入一些值。
例如:<my-component ...></my-component>
我在我的 html 中引用了它,它完美地工作。我还创建了几个指令,通过简单的正则表达式验证表单输入数据。我可以在如下形式的纯输入中使用它们:
<input type="text" validator1 validator2 validator3 />
有没有一种方法可以将这些指令中的一个或多个(还有 none 个指令)传递到我的自定义组件,而无需在组件的源代码中对它们进行硬编码?
某种...params
要评估?
在此先感谢您的帮助
瓦莱里奥
您正在寻找的模式绝对是可能的,但在您尝试的某种意义上无法通过指令实现。这是因为 Angular 是 编译的 ,这意味着你不能 not "hard-code" 一个指令(至少不能没有做不建议在生产中做的奇怪事情)。
你的组件可以接受一个名为 validators
的输入,它应该是一个函数数组(或者 class 的实例,如果你需要的话),然后用它来验证。
例如,您可以拥有以下三个超级简单的验证器:
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 或简单地将它们实例化为组件的成员 class。要将它与 DI 一起使用,验证器必须是 classes(至少就 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 中的 响应式表单感兴趣。您可以阅读 reactive forms in official documentation, or take a look at Todd Motto's article on reactive forms in Angular, or Reactive Forms in Angular by Pascal Precht on thoughtram.