Angular模板语法操作符及类型转换函数

管道操作符 ( | )

在进行数据绑定之前,表达式的结果可能需要一些转换。例如,可能希望把数字显示成金额、强制文本变成大写,或者过滤列表以及进行排序。

Angular 管道对像这样的小型转换来说是个明智的选择。 管道是一个简单的函数,它接受一个输入值,并返回转换结果。 它们很容易用于模板表达式中,只要使用管道操作符 (|) 就行了。

Angular 内置了一些管道,比如 DatePipeUpperCasePipeLowerCasePipeCurrencyPipePercentPipe。 它们全都可以直接用在任何模板中。

管道使用

管道操作符会把它左侧的表达式结果传给它右侧的管道函数。

还可以通过多个管道串联表达式:

还能对它们使用参数:

json 管道对调试绑定特别有用:

它生成的输出是这样的:

自定义管道

在这个管道的定义中体现了几个关键点:

  1. 管道是一个带有“管道元数据(pipe metadata)”装饰器的类。
  2. 这个管道类实现了 PipeTransform 接口的 transform 方法,该方法接受一个输入值和一些可选参数,并返回转换后的值。
  3. 当每个输入值被传给 transform 方法时,还会带上另一个参数,比如你这个管道就有一个 exponent(放大指数) 参数。
  4. 可以通过 @Pipe 装饰器来告诉 Angular:这是一个管道。该装饰器是从 Angular 的 core 库中引入的。
  5. 这个 @Pipe 装饰器允许你定义管道的名字,这个名字会被用在模板表达式中。它必须是一个有效的 JavaScript 标识符。 比如,你这个管道的名字是 exponentialStrength

使用时注意:

  • 你使用自定义管道的方式和内置管道完全相同。
  • 你必须在 AppModuledeclarations 数组中包含这个管道。

安全导航操作符 ( ?. ) 和空属性路径

Angular 的安全导航操作符 (?.) 是一种流畅而便利的方式,用来保护出现在属性路径中 nullundefined 值。 下例中,当 currentHero 为空时,保护视图渲染器,让它免于失败。

如果下列数据绑定中 title 属性为空,会发生什么?

这个视图仍然被渲染出来,但是显示的值是空;只能看到 “The title is”,它后面却没有任何东西。 这是合理的行为。至少应用没有崩溃。

假设模板表达式涉及属性路径,在下例中,显示一个空 (null) 英雄的 firstName

JavaScript 抛出了空引用错误,Angular 也是如此:

晕,整个视图都不见了。

如果确信 hero 属性永远不可能为空,可以声称这是合理的行为。 如果它必须不能为空,但它仍然是空值,实际上是制造了一个编程错误,它应该被捕获和修复。 这种情况应该抛出异常。

另一方面,属性路径中的空值可能会时常发生,特别是数据目前为空但最终会出现。

当等待数据的时候,视图渲染器不应该抱怨,而应该把这个空属性路径显示为空白,就像上面 title 属性那样。

不幸的是,当 currentHero 为空的时候,应用崩溃了。

可以通过用NgIf代码环绕它来解决这个问题。

或者可以尝试通过 && 来把属性路径的各部分串起来,让它在遇到第一个空值的时候,就返回空。

这些方法都有价值,但是会显得笨重,特别是当这个属性路径非常长的时候。 想象一下在一个很长的属性路径(如 a.b.c.d)中对空值提供保护。

Angular 安全导航操作符 (?.) 是在属性路径中保护空值的更加流畅、便利的方式。 表达式会在它遇到第一个空值的时候跳出。 显示是空的,但应用正常工作,而没有发生错误。

在像 a?.b?.c?.d 这样的长属性路径中,它工作得很完美。

非空断言操作符(!)

在 TypeScript 2.0 中,你可以使用 --strictNullChecks 标志强制开启严格空值检查。TypeScript 就会确保不存在意料之外的 null 或 undefined。

在这种模式下,有类型的变量默认是不允许 null 或 undefined 值的,如果有未赋值的变量,或者试图把 null 或 undefined 赋值给不允许为空的变量,类型检查器就会抛出一个错误。

如果类型检查器在运行期间无法确定一个变量是 null 或 undefined,那么它也会抛出一个错误。 你自己可能知道它不会为空,但类型检查器不知道。 所以你要告诉类型检查器,它不会为空,这时就要用到非空断言操作符。

Angular 模板中的非空断言操作符(!)也是同样的用途。

例如,在用ngIf来检查过 hero 是已定义的之后,就可以断言 hero 属性一定是已定义的

在 Angular 编译器把你的模板转换成 TypeScript 代码时,这个操作符会防止 TypeScript 报告 "hero.name 可能为 nullundefined"的错误。

与安全导航操作符不同的是,非空断言操作符不会防止出现 null 或 undefined。 它只是告诉 TypeScript 的类型检查器对特定的属性表达式,不做 "严格空值检测"。

如果你打开了严格控制检测,那就要用到这个模板操作符,而其它情况下则是可选的。

类型转换函数 $any ($any( <表达式> ))

有时候,绑定表达式可能会报类型错误,并且它不能或很难指定类型。要消除这种报错,你可以使用 $any 转换函数来把表达式转换成 any 类型。

在这个例子中,当 Angular 编译器把模板转换成 TypeScript 代码时,$any 表达式可以防止 TypeScript 编译器报错说 marker 不是 Hero 接口的成员。

$any 转换函数可以和 this 联合使用,以便访问组件中未声明过的成员。

$any 转换函数可以在绑定表达式中任何可以进行方法调用的地方使用。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复