Angular开发技巧
由于之前有幸去参加了ngChina2018开发者大会,听了will保哥分享了Angular开发技巧,自己接触Angular也有差不多快一年的时间了,所以打算对Angular开发中的一些技巧做一个整理
工具篇
所谓 “工欲善其事,必先利其器”,下面我会介绍 如何打磨 `VS Code` 这把利器
抛弃 资源管理器 ,使用快捷键 Commd + P 来查找文档,默认会展示最近打开的文档,并且支持模糊搜索文件
快速打开最近文档:前进 Ctrl+➕ 后退 Ctrl+➖
灵活使用VS Code重构功能,可以通过快捷键 Command + 对代码进行重构
安装插件 Angular Extension Pack (认准will保哥出品),这个插件集成了很多提升Angular开发效率的插件,比如:
在 TS中实用 `ng-import-*` 导入常见的类
模板编辑的时候实用 ` a-*** ` 快速使用Angular的组件和指令 (Angular v7 Snippets)
实用 ` ng-* ` 来生成常用的ng代码段,创建 Component,Directive 等 (Angular Snippets)通过快捷键把JSON转换成TS类
Ctrl+Alt+V 把粘贴板中的JSON 转为 Typescript
Ctrl+Alt+S 将选中的JSON 生成对应的 Typescript还有一个值得一提的一个比较实用的功能,通过快捷键来 快速切换组件对应的不同的文件 (Angular2-switcher)
还有很多其他功能,插件中有详细介绍 `Angular Extension Pack
安装插件 Clipboard History , 这个插件会存储你最近的拷贝的记录,方便记录和粘贴最近几次的拷贝内容
安装插件 Local History ,这个插件用于维护文件的本地历史记录。每次修改文件时,旧内容的副本都会保留在本地历史记录中,你可以随时将文件与历史记录中的任何旧版本进行比较,如果发生意外时,可以帮助我们恢复丢失的内容,需要注意的是它会生成一个 .history 的文件夹进行本地修改的备份,所以我们需要再 .gitignore 排除这个文件夹,避免将其提交到git仓储。
安装插件 Prettier - Code formatter ,这是一个代码格式化的插件,用过几个格式化的插件,个人感觉最好用的一个,更适合Angular开发
安装 Chrome 插件 Angular Angury 进行调试工作,可以查看 Component 的 State,Router Tree,NgModules的一些状态 (这个插件在复杂项目中并不是特别好用,包括对一些动态组件的支持比较差,但是在一些简单的项目中,或者新手在学习的时候安装这个插件比较方便调试排错)
开发篇
下面会介绍一些Angular开发中的技巧
使用模板语言 as , 使用 as 对一些嵌套结构深的属性进行重命名
改进前:<div *ngFor="let queue of fileUploadQueues">
<div class="icon" *ngIf="queue.result.file.icon">{{ queue.result.file.icon }}</div>
<div class="name" *ngIf="queue.result.file.name">{{ queue.result.file.name }}</div>
<div class="size" *ngIf="queue.result.file.size">{{ queue.result.file.size }}</div>
</div>改进后:
<div *ngFor="let queue of fileUploadQueues">
<ng-container *ngIf="queue.result.file as file">
<div class="icon" *ngIf="file.icon">{{ file.icon }}</div>
<div class="name" *ngIf="file.name">{{ file.name }}</div>
<div class="size" *ngIf="file.size">{{ file.size }}</div>
</ng-container>
</div>灵活使用 *ngIfElse ,很多人其实一直在写 *ngIf 并不知道其实Angular支持 else 的写法 *ngIf="条件 ; else 模板" ,看看下面这两段代码
改进前:
<div *ngIf="(data$ | async).length > 0">
...
</div>
<div *ngIf="!(data$ | async).length > 0">
没有数据
</div>改进后:
<div *ngIf="(data$ | async).length > 0; else emptyTemplate;">
...
</div>
<ng-template #emptyTemplate>
没有数据
</ng-template>改进前的写法,也能实现同样的效果,但是因为数据是通过 async 订阅的,第一种写法相当于进行了两次订阅,当然也可以用 as 来解决,这里只是一个示例。
还有一种情况,在条件多的时候,通过第一种方式写的话,如果条件有修改的话,必须要对取反后的条件进行维护, 而用 ngIfElse 的方式则只需要进行一次维护。使用 ng-container 对代码进行整理,使代码更清晰,提升代码的可读性
<ng-container *ngIf="type === 1">
...
</ng-container>
<ng-container *ngIf="type === 2">
...
</ng-container>
<ng-container *ngIf="type === 3">
...
</ng-container>@ViewChild 读取指定类型的实例
<input #input thyInput [thyAutofocus]="true" />
上面这行代码有三个实例 ElementRef 、 ThyInputComponent 、 ThyAutoFocusDirective ,在某些情况下如果我们要获取指定类型的实例应该怎么做呢?
@ViewChild('input', { read:ThyInputComponent }) inputComponent : ThyInputComponent ;使用 async 管道,直接在模板中订阅流,而不必将结果存储在中间属性中,当组件被销毁时,Angular将会自动取消订阅。
<div *ngFor="let item of data$ | async">
...
</div>在一些情况下,我们可能需要重复使用订阅的数据,但是我们又不能每次使用的时候都用 async 去订阅,所以我们可以通过刚才说的 as 对齐进行重命名。
<div *ngFor="let item of data$ | async as data">
<span>一共有{{data.length}}条数据</span>
</div>使用 takeUntil 来管理订阅
在某些复杂的业务中,我们可能需要订阅多个流,一个一个去取消订阅又繁琐,又会产生很多冗余代码,不利于代码的维护。这时候我们可以 takeUntil 来管理多个订阅,统一取消订阅。private _ngUnsubscribe$ = new Subject(); ngOnInit() {
this.students$.pipe(
takeUntil(_ngUnsubscribe$)
).subscribe(() => {
...
});
this.books$.pipe(
takeUntil(_ngUnsubscribe$)
).subscribe(() => {
...
});
}
ngOnDestroy() {
this._ngUnsubscribe$.next();
this._ngUnsubscribe$.complete();
}合理使用 ngZone runOutsideAngular 来提升应用性能
我们知道Angular可以自动处理变化检测,这是因为它使用了 zone.js ,简单的来说, zone.js 就是通过打补丁的方式来拦截浏览器的事件,然后进行变化检测,但是变化检测是极其消耗资源的,如果绑定了大量的事件,那么就会造成性能问题,所以我们可以使用 runOutsideAngular 来减少不必要的变化检测。this.ngZone.runOutsideAngular(() => {
this.renderer.listen(this.elementRef.nativeElement, 'keydown', event => {
const keyCode = event.which || event.keyCode;
if (keyCode === keycodes.ENTER) {
event.preventDefault();
this.ngZone.run(() => {
this.thyEnter.emit(event);
});
}
});
});上面这段代码是绑定一个回车事件,如果不使用 runOutsideAngular 的话,只要触发键盘输入事件,就会执行变化检测,这时候我们可以用 runOutsideAngular 在只有为enter事件的时候,去调用 ngZone.run() 主动触发变化检测
灵活使用 ngTemplateOutlet 来实现递归
<ng-container *ngFor="let node of treeNodes;" [ngTemplateOutlet]="nodeTemplate"
[ngTemplateOutletContext]="{node: node}">
</ng-container> <ng-template #nodeTemplate let-node="node">
<div class='title'>{{node.title}}</div>
<ng-container *ngFor="let child of node?.children;" [ngTemplateOutlet]="nodeTemplate"
[ngTemplateOutletContext]="{node: child}">
</ng-container>
</ng-template>在我们实际开发的过程中,经常会展示一些树形结构的数据,如果业务场景比较简单,可以通过Angular的 ngTemplateOutlet 来实现递归展示,如果业务复杂,建议还是通过组件的方式来实现。
写在最后
上面是我这一年Angular开发的过程中积累的一些小技巧(可能还有没想起来的,我想起来会慢慢的往上补),大家如果发现有错误的地方,请指正。其实去年就写好这篇文章,但是总感觉缺点什么,不过无所谓了~~ 希望能给Angular学习者提供帮助~
Worktile官网:www.worktile.com
本文作者:王凯
文章首发于「Worktile官方博客」,转载请注明来源。
Angular开发技巧的更多相关文章
- AngularJS进阶(三十一)AngularJS项目开发技巧之获取模态对话框中的组件ID
AngularJS项目开发技巧之获取模态对话框中的组件ID 需求 出于项目开发需求,需要实现的业务逻辑是:药店端点击查看"已发货""已收货"订单详情时,模块弹出 ...
- SQL开发技巧(二)
本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上-- 文章系列目录 SQL开发技巧(一) SQL开 ...
- DelphiXE2 DataSnap开发技巧收集
DelphiXE2 DataSnap开发技巧收集 作者: 2012-08-07 09:12:52 分类:Delphi 标签: 作为DelphiXE2 DataSnap开发的私家锦囊, ...
- delphi XE5下安卓开发技巧
delphi XE5下安卓开发技巧 一.手机快捷方式显示中文名称 project->options->Version Info-label(改成需要显示的中文名即可),但是需要安装到安卓手 ...
- 经典收藏 50个jQuery Mobile开发技巧集萃
http://www.cnblogs.com/chu888chu888/archive/2011/11/10/2244181.html 1.Backbone移动实例 这是在Safari中运行的一款Ba ...
- 移动 Web 开发技巧之(后续)
昨天的<移动 Web 开发技巧>的这篇文章,大家反响不错,因为这些问题在大家日常写移动端的页面时经常遇到的.所以那个文章还是超级实用的,那么我们今天继续来分享一下移动端的web开发技巧吧, ...
- Maven 安装以及一些开发技巧
解压 apache-maven-3.2.5 在conf ->sites中配置repository 的路径. Eclipse 配置 maven 2. 3. 一些小BUG 或开发技巧 eclipse ...
- thinkphp开发技巧经验分享
thinkphp开发技巧经验分享 www.111cn.net 编辑:flyfox 来源:转载 这里我给大家总结一个朋友学习thinkphp时的一些笔记了,从变量到内置模板引擎及系统变量等等的笔记了,同 ...
- Java 8的五大开发技巧
转载:http://geek.csdn.net/news/detail/94219 在Java 9发布之前,我们来分享一些Java 8开发技巧,本文翻译自JetBrains高级开发主管Trisha G ...
随机推荐
- BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树
BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...
- 旅行app(游记、攻略、私人定制) | 顺便游旅行H5移动端实例
<顺便游旅行>是一款H5移动端旅行app,提供目的地(国内.国外.周边)搜索.旅游攻略查询.游记分享.私人定制4大模块,类似携程.同程.去哪儿.马蜂窝移动端,只不过顺便游app界面更为简洁 ...
- MYSQL——数据库存储引擎!
本人安装mysql版本为:mysql Ver 14.14 Distrib 5.7.18, for Win64 (x86_64),查看mysql的版本号方式:cmd-->mysql --vers ...
- 关于throw、throws、try--catch的问题
首先回顾概念 throws表示出现异常的一种可能性,并不一定会发生这些异常 throw则是抛出了异常,执行throw则一定抛出了某种异常 try--catch try语句用大括号{}指定了一段代码,该 ...
- Go语言中的面向对象
前言 如果说最纯粹的面向对象语言,我觉得是Java无疑.而且Java语言的面向对象也是很直观,很容易理解的.class是基础,其他都是要写在class里的. 最近学习了Go语言,有了一些对比和思考.虽 ...
- JAVA基础第五章-集合框架Map篇
业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...
- SSL,TLS
今天突然收到邮件说SSL不能用了,基于SSL的HTTPS协议不通了,怎么办? java/android 的网络编程简直一窍不通,平时都是用到了问百度.只能恶补有关网络的知识了. 传输协议: 传输协议中 ...
- ssm日期格式转换
ssm日期格式转换 1 需求 前端传入字符串类型日期转化成java中的Date类型,存入数据库中;将数据库中的日期类型通过jstl标签在前端页面转换成字符串类型. 2 步骤 2.1 ...
- .Net 事件总线之Autofac解耦
事件总线是通过一个中间服务,剥离了常规事件的发布与订阅(消费)强依赖关系的一种技术实现.事件总线的基础知识可参考圣杰的博客[事件总线知多少] 本片博客不再详细概述事件总线基础知识,核心点放置使用Aut ...
- .NET 平台上C#语言的基本技术点
第一次用画图3D画的知识点,有点丑..........开始Csharp之路