微信号:frontshow

介绍:InfoQ大前端技术社群:囊括前端、移动、Node全栈一线技术,紧跟业界发展步伐。

Angular的这10个特性,你可能不知道

2018-08-16 17:59 李志 译
作者|angular-guru.com
译者|李志

大型框架 Angular 中隐藏着许多你可能不知道的有趣特性,本文介绍了其中 10 种。一起来看看吧!

Angular 是一个大型框架,大多数人可能都用过其中的一小部分。但在它平凡的外表之下,隐藏着许多有用的特性,可以提高我们的工作效率。本文将介绍 Angular 的 10 种你可能没有听说过但却十分有用的特性。

Angular 中最容易被忽略却很有用的特性之一就是其提供的各种管道(pipe)。那么我们就先从这里讲起,来看看一些有用的管道吧!

1.KeyValuePipe

这是 Angluar 6.1 的主要特性之一。之前的 *ngFor 指令只允许你迭代数组或可迭代的结构体。如果想要迭代对象中的属性或 Map 中的项时,就会很麻烦。

这时,KeyValuePipe 就能帮我们大忙啦!我们只需将我们想要迭代的对象放到管道里,接下来的事就可以全权交给 *ngFor 处理了。例如:

@Component({
  selector: 'app-list',
  template: `
  <ul>
    <li *ngFor="let word of words | keyvalue">
      {{ word.key }}: {{ word.value }}
    </li>
  </ul>
  `
})
export class AppListComponent {
  words = new Map([[1, 'Angular'], [2, 'Guru']]);
}

KeyValuePipe 的文档:https://angular.io/api/common/KeyValuePipe

2. 切片管道(Slice Pipe)

渲染一组项目并操作大量 DOM 节点通常是一个很耗资源的任务,因此有时我们希望减少需要显示的项目的数量。这种操作有许多实现方法,而 Angular 给出了一个十分简单的解决方案——SlicePipe,可作为 ngFor 表达式的一部分。

例如,我们想要显示一个数组中的前 10 项,就可以使用 SlicePipe 来完成。具体做法如下:

<ul>
    <li *ngFor="let item of items | slice:0:10">{{ item }}</li>
</ul>

SlicePipe 文档:https://angular.io/api/common/SlicePipe

3. 小数管道(Decimal Pipe)

这是一个十分简单的管道,用于格式化数字,比如控制小数点后显示的数字个数。如果你比较喜欢让自己的数字的显示格式更容易阅读,比如每隔一个千位添加一个逗号(如 1000 显示为 1,000),也可以用这个管道来实现。

与这个管道相关的另一个特性是 formatNumber 函数,它是 @angular/common 的一部分,让你可以以编程的方式应用相同的格式,而不是在视图中使用管道。

<p>Your number is: {{ value | number }}</p>

DecimalPipe 的文档:https://angular.io/api/common/DecimalPipe

formatNumber 的文档:https://angular.io/api/common/formatNumber

4. JSON 管道(JSON Pipe)

JSON 管道非常有用,尤其是在调试的时候。它可以让你在视图中以字符串的格式显示一个对象。比起在代码中打断点调试,这种方法更为简单易用。

JSON 管道的用法很简单,只需要将管道添加到你想要显示的对象后面即可。

<p>{{ myObj | json }}</p>

JsonPipe 文档: https://angular.io/api/common/JsonPipe

5. 标题和元服务

该特性在涉及搜索引擎和社交平台(如 Google、Twitter、Facebook 等)时尤其实用。这些平台会查找你页面上的< meta >标签用于描述页面内容,提供标题、描述、图像等等。

例如,下面这个博客的每篇博文都会有不同的标题、描述和图片。为保证每篇博文获得正确信息,我们可以使用元服务(meta service)。该服务允许我们动态添加和更新页面上的 meta 标签。具体做法如下:

export class AppComponent {
  constructor(meta: Meta) {
    // Twitter Markup
    this.meta.updateTag({ name: 'twitter:card', content: 'summary_large_image' });
    this.meta.updateTag({ name: 'twitter:site', content: '@TheAngularGuru' });
    this.meta.updateTag({ name: 'twitter:title', content: 'Article title' });
    this.meta.updateTag({ name: 'twitter:description', content: 'Article description' });
    this.meta.updateTag({ name: 'twitter:image', content: 'image.jpg' });
  }
}

另外,Angular 还提供了一个 Title 服务。也许你已经猜到,该服务的功能是更新浏览器窗口的标题。更新标题的通常做法是为文件头的< title >标签设置一个值,但这样我们就不能使用标准的 Angular 绑定(如<title>{{ myTitle }}</title>),因为< head >不属于 Angular 组件。因此,我们必须改用 Title 服务。该服务的使用方法极其简单:

export class AppComponent {
    constructor(title: Title) {
        title.setTitle('Window Title here');
    }
}

Meta 的文档:https://angular.io/api/platform-browser/Meta

Title 的文档:https://angular.io/api/platform-browser/Title

6. ng-container

你是否有过这样的经历:想要将两个结构指令放在一个元素里,搞了半天却发现并不能这样做……

或者,你希望使用 ngTemplateOutlet 插入一个模板,结果发现插入的模板并不是子元素,而是变成了兄弟元素。

这非常糟心。因为你为了实现以上功能,需要添加一个随机的包裹< div >元素。而这种实现方法不仅不理想,还会污染你干净的 DOM 结构。

幸运的是,我们还有 ng-container 元素,可以避免上述问题。该元素只在开发过程中出现,实际上并不会在 DOM 上增加任何新元素,因此可以用来解决包括上述问题在内的很多问题。

例如,两个结构指令的问题可以用以下方式解决:

<ng-container *ngIf="condition">
    <div *ngFor="let item of items">{{ item }}</div>
</ng-container>

插入模板作为子元素:

<div>
    <ng-container [ngTemplateOutlet]="template"></ng-container>
</div>

上面两个例子只是该元素的诸多用法中的冰山一角。我相信你一定会发掘出它的更多应用!

7. 属性装饰器(Attribute Decorator)

我们都知道,@Input 和 @Output 是用来绑定和释放事件的属性装饰器。其实还有另一种比较小众的装饰器,@Attribute 装饰器。

这个装饰器在某些方面和 @Input 装饰器有点像,因为它可以用于向组件传递值。

这种属性绑定和 AngularJS 的字面量作用域(literal scope)绑定很像:

scope: {
    type: '@'
}

首先我们来看一下这种绑定的不足之处:

  • 所有值都是以字符串格式提供的

  • 值是静态的,不能像绑定一样被更新

  • 无法对其使用 [attribute] 绑定语法尽管有其局限性,如果我们不需要在意以上问题时,该方法还是能为我们提供很多方便,因为这些属性不属于绑定,在变更检测中不需要检查它们。

@Attribute 装饰器的使用方法和 @Input 装饰器相似:

@Attribute() type: string;

Attribute 指令的文档: https://angular.io/api/core/Attribute

更多内容还可参见这篇关于 Attribute 指令的文章:https://netbasal.com/getting-to-know-the-attribute-decorator-in-angular-4f7c9fb61243

8. 分析变更检测

我想大家一定都知道,在所有 Angular CLI 项目中,main.ts 文件都会调用 enableProdMode 函数。其实,该文件还可以调用 enableDebugMode 函数。你可能会想,如果代码不在生产模式下运行,一定是在调试模式下运行,但事实并非如此(至少在调用本函数时不是这样的)。

通过调用这个函数,我们在 window.ng 对象上会获得一个额外的工具,叫做 profiler。profiler 中有一个函数叫做 timeChangeDetection。当这个函数被调用时,会在控制台打印出变更检测的周期和每个周期的运行时间。

当需要分析性能较差的应用时,这个函数尤其有用。要调用这一函数,只需在引导代码中添加如下片段:

platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
  const applicationRef = ref.injector.get(ApplicationRef);
  const appComponent = applicationRef.components[0];
  enableDebugTools(appComponent);
});

若要开始进行分析,只需在 DevTools 控制台上运行如下代码:

ng.profiler.timeChangeDetection();
9. NgPlural

在很多应用中,你可能需要描述一系列项目,而此时语言是个很麻烦的问题。比如,我们经常需要处理名词的单复数问题。例如,考虑如下三种情况:

  • 列表中没有项(no items)

  • 列表中有一个项(1 item)

  • 列表中有两个项(2 items)

而针对这一情况,ngPlural 指令就是一个非常易用的处理方式。上面的例子可以用以下方式处理:

<p [ngPlural]="value">
  <ng-template ngPluralCase="=0">There are no items</ng-template>
  <ng-template ngPluralCase="=1">There is 1 item</ng-template>
  <ng-template ngPluralCase="other">There are {{ value }} items</ng-template>
</p>

NgPlural 文档:https://angular.io/api/common/NgPlural

NgPluralCase 文档:https://angular.io/api/common/NgPluralCase

10. ngPreserveWhitespaces 和 NgNonBindable

我把这两条指令放在一起来讲,因为在实际应用中,当需要对内容进行格式化时,这两条指令往往都会被用到。

在 Angular 5 中,angularCompilerOptions 里加入了 preserveWhitespaces 选项。如果该选项被设置为 false,编译器会移除所有不必要的空格。这对代码格式会有一些小小的影响,但却可以帮助我们缩小包的大小。

但是,有时候我们也希望完整地保留空格。如果希望整个组件保留其空格,只需要在组件装饰器中使用如下选项:

@Component({
    selector: 'app',
    templateUrl: './app.component.html',
    preserveWhitespace: true
})

有时,我们可能只需要在某个特定的 DOM 元素中保留空格。这时,我们可以使用 ngPreserveWhitespaces 指令,如下所示:

<div ngPreserveWhitespaces>
    <!-- All whitespace here will be preserved -->
</div>

另外,我们有时可能需要在文档中使用{{ }},但 Angular 会把这一符号看作插值,并会计算括号中内容的值。这时,可以将 ngNonBindable 指令插入父元素中,让 Angular 忽略其中的括号。示例用法如下:

<span ngNonBindable>{{ this will not be evaluated }}</span>

10 个你可能不知道的 Angular 特性已经介绍完毕,希望这些特性能够给你们带来帮助!

  英文原文

https://angular-guru.com/blog/angular-unknown-features

  课程推荐

推荐给你极客时间火爆专栏 --《深入拆解 Java 虚拟机》,作者为 Oracle Labs 高级研究员,已突破 1w+订阅。四大模块,覆盖 JVM 所有知识点,带你全方位拆解 JVM,系统学习 Java 性能分析、调优,掌握进阶必备技能!

扫码,即可试读此专栏的前三篇文章。

 
前端之巅 更多文章 专访尤雨溪:先别管4.0了,Vue CLI重构了解一下 Chrome十周年版更新了,你第一次用它是什么时候? 用实例告诉你如何重构带有坏味道的代码 Web性能分析工具WebpageTest详解 谷歌推出最新AngularJS升级工具,可快速迁移至Angular
猜您喜欢 不要忽视C语言 全面了解docker,赢在精彩问答中! 往期精选(一)| 数字时代性爱指南 知识点归纳(1) 独角兽的”寒冬“@峰瑞资本李丰