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

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

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

src/app/app.component.html
The current hero's name is {{currentHero?.name}}

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

src/app/app.component.html
The title is {{title}}

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

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

The null hero's name is {{nullHero.name}}

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

TypeError: Cannot read property 'name' of null in [null].

晕,整个视图都不见了

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

另一方面,属性路径中的空值可能会时常发生,特别是当我们知道数据最终会出现。

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

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

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

src/app/app.component.html
<!--No hero, div not displayed, no error --> <div *ngIf="nullHero">The null hero's name is {{nullHero.name}}</div>

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

src/app/app.component.html
The null hero's name is {{nullHero && nullHero.name}}

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

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

src/app/app.component.html
<!-- No hero, no problem! --> The null hero's name is {{nullHero?.name}}

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


非空断言操作符(!

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

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

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

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

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

src/app/app.component.html
<!--No hero, no text --> <div *ngIf="hero"> The hero's name is {{hero!.name}} </div>

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

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

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

相关文章
相关标签/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。
本站公众号
   欢迎关注本站公众号,获取更多程序园信息
开发小院