浅谈 Angular 项目实战

浅谈 Angular 项目实战

https://www.cnblogs.com/nzbin/p/9038162.htmljavascript

 

为何使用 Angular

我不是 Angular 的布道者,但现在痴迷 Angular,使用 Angular 作项目让我有一种兴奋感。目前的三大主流前端框架都研究过,博客中也有三者的相关教程,最先接触的是 React,可是并无实际的项目经验,只作过一些 Demo 。使用 Vue 作过一个比较复杂的移动端大数据项目,技术栈采用 Framework7 + Vue + Vuex,总体效果仍是满意的。css

由于去年的项目几乎都是后台管理系统,因此框架用的很少,主要仍是传统方式开发,后期为了改善前端开发体验,逐步在向框架靠拢。经过第三方 Bootstrap 框架对比发现,大多都有 Angular 版本,并且组件库是最全的,React 和 Vue 版本的组件库相对匮乏一些。事实证实使用 Angular 开发大型后台管理系统具备独特的优点。另外一方面, Angular 是困难度复杂度的一个缩影,它汇聚了设计模式、设计哲学、工程化思想,对于前端开发是质的飞越。 除此以外,Angular 的文档让我着迷,除了基本的教程以外,其核心知识是最让我津津乐道的地方,不只能够了解技术内幕,甚至能够学习不少基础知识,都很是实用,对于前端新手以及业余爱好者都有很大的帮助做用。html

使用 Angular 开发须要很是多的前置知识,好比 TypeScript、RxJS 等,因此学习成本比较高,这也是不少人望而却步的一个缘由。在通过很长时间的学习及准备以后,终于在今年有了项目实战的机会,项目很小,是整个系统中的一个独立模块,可是几乎全部知识都有涉猎,可谓“麻雀虽小五脏俱全”。本文就是对该项目的一些总结及思考。前端

搭建开发环境

开发环境的搭建很是简单,使用 Angular CLI 几乎能够完成全部工做,可是在与后端联调接口的时候,还须要作一些自定义配置。如下是 proxy.config.json 文件的基本设置:java

{
  "/api": { "target": "http://localhost:3000", "secure": false } }

Angular CLI 的使用贯穿整个项目,从开发到打包无处不在,这也是 Angular 工程化的体现。由于 CLI 的参数很是多,必须仔细阅读文档,合理设置参数,全部的需求几乎都能在参数中找到。其中使用 ng build 打包后可能会有资源引用错误的问题,能够看一下使用 ng build 构建后资源地址引用错误的问题react

在联调接口时,可能还会遇到传输 Cookie 的问题,具体能够参见 关于 Angular 跨域请求携带 Cookie 的问题git

选择 UI 库

由于项目比较小,开发之初打算本身写组件,好比分页,但实际状况比较复杂,尤为刚接触 Angular,对于组件交互、异步数据还有点懵,尝试写了一下,仍然有不少问题,因此最终仍是选择比较成熟的 UI 库。github

UI 库的选择须要根据样式决定,好比个人项目使用的是 Bootstrap,因此 UI 库选择了和 Bootstrap 相关的 ngx-bootstrap。对于后台管理系统,经常使用的组件无外乎弹窗、分页、标签页等。对于更复杂的系统,也能够根据本身的状况选择其余组件更丰富的 UI 库,好比 PrimeNG 等。面试

组件库主要使用了弹窗及分页,其中 ngx-bootstrap 的弹窗是一个比价优秀的组件,信息输入及提示都会用到。如下是一个自定义 Alert 弹窗,经过 Service 共享组件便可。ajax

modal-alert.component.html 中的代码是整个组件的 HTML 结构,有两个变量及一个实例方法。

<div class="modal-header"> <h4 class="modal-title pull-left">{{title}}</h4> <button type="button" class="close pull-right" aria-label="Close" (click)="bsModalRef.hide()"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> {{content}} </div> <div class="modal-footer"> <button type="button" class="btn btn-default" (click)="bsModalRef.hide()">关闭</button> </div>

在 modal-alert.component.ts 中定义变量及组件实例。

import { Component, OnInit } from '@angular/core'; import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service'; @Component({ selector: 'app-modal-alert', templateUrl: './modal-alert.component.html', styleUrls: ['./modal-alert.component.css'] }) export class ModalAlertComponent implements OnInit { title: string; content: string; constructor(public bsModalRef: BsModalRef) {} ngOnInit() { } }

在 modal.service.ts 中定义了组件的公共方法 modalAlert() 。

export class ModalService {  modalRef: BsModalRef; constructor(private modalService: BsModalService, private http: HttpClient) { } modalAlert(msg: string) { const initialState = {  content: msg,  title: '提示信息' }; this.modalRef = this.modalService.show(ModalAlertComponent, {  initialState: initialState,  class: 'modal-sm' } ); } }

最后还须要在 app.module.ts 中定义 entryComponents,好比:

@NgModule({ declarations: [ ... ], imports: [ ... ], ... entryComponents: [ModalAlertComponent, ModalConfirmComponent] })

还有一点须要注意,在使用模板引用变量时,不要和函数名重名,有时图省事可能会忽略这一点。好比如下代码会报错:

<ng-template #Alert> ... <div class="modal-footer"> <button type="button" class="btn btn-primary" (click)="Alert()">肯定</button> </div> </ng-template>

表单的多样性

Angular 提供了两种表单,模板驱动表单响应式表单。其中模板驱动表单简单灵活,适用于不复杂的表单数据。

关于表单这一块,咱们将 Angular 和 Vue 放在一块儿说,Vue 的表单绑定就属于模板驱动表单。不过 Angular 的模板驱动表单并无复选框的多选绑定,若是有这个需求,能够选择更加灵活强大的响应式表单进行数据绑定。其实,对于数组形式的数据可使用自然的 select 多选框实现。好比如下代码:

<div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" multiple required [(ngModel)]="model.power" name="power"> <option *ngFor="let pow of powers" [value]="pow">{{pow}}</option> </select> </div>

关于数组类型的数据,在 Vue 中有两种绑定方法,分别是复选框及 select 多选框。然而复选框的 value 值只有 true 或者 false,而 select 多选框的 value 值就是数组。因此 Vue 对复选框的多选操做进行了处理,而 Angular 没有,须要你本身处理。经过 Angular 的响应式表单能够很容易实现。可是对于模板驱动表单也能够用另类的方式实现,好比手动实现一个双向数据绑定,虽然有点麻烦,但倒是可行的。关于这个话题我放到下一篇文章中说明。

官方文档中关于表单的内容很是详细,从用户输入到绑定再到校验,比着葫芦画瓢就能够轻松实现双向数据绑定。我很是喜欢 Angular 中 [()] (盒子里的香蕉)这种数据绑定方式,经过阅读官方文档的核心知识,对于双向数据绑定的认识有了质的提升。

管道之数据映射

管道的用处很是大,就我我的而言,时间转换及数据映射比较常见。我主要想讨论一下数据映射的问题。起初打算本身写关于数据映射的管道,可是想了想,难道不一样的数据映射都单独写一个管道?而后我就想有没有自带的管道实现数据映射,仔细翻了翻文档,最后终于找到了,I18nPluralPipe 就是用于映射数据的。咱们用一个最多见的数据映射例子说明,好比保存性别数据时,1 表示男,2 表示女。

@Component({
  selector: 'i18n-plural-pipe', template: `<div>{{ sex | i18nPlural: sexMapping }}</div>` }) export class I18nPluralPipeComponent { sex: string = '1'; sexMapping: {[k: string]: string} = {'=1': '男', '=2': '女', 'other': '其余'}; }

I18nPluralPipe 使用了 ICU 格式,确实长见识了。这个管道真的很好用,至少不用对每个数据映射都写一个专用管道了。

上方示例代码中, sexMapping 使用接口中的可索引的类型进行定义。

异步开发之 RxJS

关于 RxJS 是一个比较复杂的话题,我也没有彻底弄明白。Angular 官网的定义以下:

响应式编程是一种面向数据流和变动传播的异步编程范式(Wikipedia)。RxJS(响应式扩展的 JavaScript 版)是一个使用可观察对象进行响应式编程的库,它让组合异步代码和基于回调的代码变得更简单 (RxJS Docs)。

关于异步开发的历史在面试中有遇到过,能够说的东西不少,好比回调函数、Promise、迭代器和生成器、async 和 await,除此以外,RxJS 中的可观察对象(Observable)应该是下一个更强大的异步编程方式。Angular 官网对可观察对象(Observable)和承诺(Promise)进行了对比

须要特别注意的就是,只有当订阅 Observable 的实例时,它才会开始发布值。 订阅时要先调用该实例的 subscribe()方法,并把一个观察者对象传给它,用来接收通知。我刚开始使用时,也是由于这个缘由被坑了一把。如下是一个很简单的官方示例:

import { ajax } from 'rxjs/ajax'; // 建立一个发送 AJAX 请求的 Observable 对象 const apiData = ajax('/api/data'); // 订阅请求 apiData.subscribe(res => console.log(res.status, res.response));

总结

这个简单的小项目用了大约一周多的时间,Angular 算是入门了,关于 Angular 还有很是多值得深究的知识。总体而言,Angular + TypeScript 的开发方式很是舒服,VSCode 对 TS 的支持很是完美,语法提示、自动补全都很方便,强类型语言是前端开发的趋势。使用 Angular 开发,正如我文章开头提到的同样,不只仅是学习一个框架,而是学习一种思想,了解更加优秀的开发模式、开源项目,可让本身始终站在技术的前沿,这是我最大的收获。

感谢您的阅读,若是您对个人文章感兴趣,能够关注个人博客,我是叙帝利,下篇文章再见!

仿 Windows 照片查看器插件 https://github.com/nzbin/photoviewer

简化类名的轻量级 CSS 框架 https://github.com/nzbin/snack

与任意 UI 框架搭配使用的通用辅助类 https://github.com/nzbin/snack-helper

单元素纯 CSS 加载动画 https://github.com/nzbin/three-dots

相关文章
相关标签/搜索