要将数字直接作为数字@Input 传递给组件,或者将true/false 作为布尔值@Input,甚至是数组,而不使用Angular 的Property binding,我们可以利用函数和Angular's CDK Coercion 的类型(如果我们不想依赖 @angular/cdk,也可以创建我们自己的类型)。
例如,要将数字@Input 传递给组件,我们可以执行以下操作:
import { coerceNumberProperty, NumberInput } from '@angular/cdk/coercion';
@Input()
get total() { return this._total; }
set total(value: NumberInput) {
// `coerceNumberProperty` turns any value coming in from the view into a number, allowing the
// consumer to use a shorthand string while storing the parsed number in memory. E.g. the consumer can write:
// `<app-total total="500"></app-total>` instead of `<app-total [total]="500"></app-total>`.
// The second parameter specifies a fallback value to be used if the value can't be parsed to a number.
this._total = coerceNumberProperty(value, 0);
}
private _total = 0;
这允许消费者在将解析后的数字存储在内存中时使用速记字符串,如下所示:
<app-total mensaje="Total por pagar: " total="5000"></app-total>
如果我们不想使用 CDK 的内置函数和类型,我们可以在 components/src/cdk/coercion 文件夹下的 Angular Components repo 中查看它们的定义。
例如,我们必须定义以下类型和函数来处理number property:
/**
* Type describing the allowed values for a number input
*/
export type NumberInput = string | number | null | undefined;
/** Coerces a data-bound value (typically a string) to a number. */
export function coerceNumberProperty(value: any): number;
export function coerceNumberProperty<D>(value: any, fallback: D): number | D;
export function coerceNumberProperty(value: any, fallbackValue = 0) {
return _isNumberValue(value) ? Number(value) : fallbackValue;
}
/**
* Whether the provided value is considered a number.
*/
export function _isNumberValue(value: any): boolean {
// parseFloat(value) handles most of the cases we're interested in (it treats null, empty string,
// and other non-number values as NaN, where Number just uses 0) but it considers the string
// '123hello' to be a valid number. Therefore we also check if Number(value) is NaN.
return !isNaN(parseFloat(value as any)) && !isNaN(Number(value));
}
boolean-property、string-array 和array 的功能和类型也是如此。