# Angular4开发文档 **Repository Path**: cjk-l/AngularReadMe ## Basic Information - **Project Name**: Angular4开发文档 - **Description**: Angular4开发文档 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2021-10-20 - **Last Updated**: 2021-10-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Angular 4.0 上手开发 ###### Angular 4 是Google推出的一个跨平台全终端的单页面应用开发框架,作为前端三架马车之一的Angular和其二的React和Vue.js相比,有如下优点: - 由于Google的目的是推出一个完整解决方案,所以官方默认提供的类库(比如routing,http,依赖性注入(DI)等)非常完整,无需自己选择。React的一大痛点就是选择太多导致在配置寻找组件和类库的过程中消耗太多精力,当然从另一方面看这也是其优势,选择众多且自由。 - 官方支持TypeScript(微软出品,是JavaScript的超集,是 JavaScript 的强类型版本)作为首选编程语言,使得开发脚本语言的一些问题可以更早更方便的找到。 - RxJS友好使得响应式编程在Augular2中变得极为容易(Google开发的框架依赖这么多的微软的产品,可见微软的转型还是很成功的) - 支持NativeScript甚至ReactNative等进行原生Android/iOS应用开发(React支持React Native) 支持服务器端渲染(React也支持) ###### 但总体来讲,Angular4更适合从原生App开发或后端Java/.Net等转型过来开发前端的程序员,因为它的开发模型更接近于传统强类型语言的模式,加上官方内建的组件和类库比较完整,有官方中文网站 [在线服务](https://www.angular.cn/) ,学习曲线要低一些。有过Angular 1.x 开发经验的同学要注意了,虽然只有一个版本号的差距,但2.x和1.x是完全不同的,不要奢望1.x的应用会平滑迁移到2.x。由于Angular4完全向后兼容,所以Angular2的大多数组件在Angular4的环境下都能够正常使用。这个版本的更新很多是bug fix,新的feature并不多。 ###### Angular4 支持大多数常用浏览器,包括下列版本: [![Sauce Test Status](https://saucelabs.com/browser-matrix/angular2-ci.svg)](https://saucelabs.com/u/angular2-ci) *Safari (7+), iOS (7+), Edge (14) and IE mobile (11) are tested on [BrowserStack][browserstack].* #### AngularJS VS Angular ###### Angular1.x显然非常成功,那么,为什么要剧烈地转向Angular2? ###### AngularJS最大版本号只有1.x,而2.x/4.x的版本号都是针对于全新的框架Angular。但不能说Angular和AngularJS一点关系都没有,至少名字还是很像的!回忆一下AngularJS被人念念不忘的特性,双向数据绑定,MVC,指令,服务,过滤器,模块化,脏检查机制,依赖注入,Scope,路由,表单校验等等。 ###### 剔除的部分: - ng-controller指令:控制器主要是业务逻辑的控制部分 - $scope概念:很强大又很复杂 - 数据双向绑定:数据双向流通可能导致数据的震荡(故才有最多检查10次的限制,10次之后还不稳定就报错) ###### 保留/改善的部分: - 路由嵌套:AngularJS自带的路由系统是不能嵌套路由的,到了Angular你想怎么嵌套就怎么嵌套 - 过滤器(Filter)变成管道(Pipe),概念的变化 - 依赖注入机制:直接在构造器中注入,还有分层依赖注入的概念 - 指令写法: - (事件) ng-click变成(click) - [属性] href = “{{}}”可以写成 [href] - [(ngModel)]代替以前的ng-model - *ngFor 代替 ng-repeat,不适用于对象,适用任何有Symbol.iterator属性的数据结构(能用for…of来访问),比如数组,集合等 - *ngIf 代替 ng-if,去掉ng-show,ng-hide - 模版,数据绑定,服务,模块,脏检查机制等 ###### 新增的部分: - 组件化:Angular的核心所在 - Typescript作为默认的开发语言 - ZoneJS监听所有(可能导致数据变化)的异步事件 - 支持服务端渲染 - 编辑热加载 #### 代码编辑器 ###### IDE的选择也比较多,免费的Visual Studio Code 和 Atom,收费的有WebStorm,IDEA。我们这里推荐采用 Visual Studio Code,可以到 https://code.visualstudio.com/ 下载 Windows/Linux/MacOS 版本。 #### 环境配置要求node ###### Angular4.0需要nodejs,npm版本,如果已安装nodejs,请使用 node -v 和 npm -v 来检查版本。 ###### 这里推荐一个切换node版本号的工具 --> [nvm](https://segmentfault.com/a/1190000007612011)(当然还有别的切换node版本的工具比如n[(安装教程)](http://blog.csdn.net/dcatfly/article/details/75201172)。该工具可以通过npm进行下载配置。 ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlr9bd4tkj20nf0fb74a.jpg) > Node.js官方地址[在线服务](https://nodejs.org/en/)。 #### TypeScript ###### Angular编写新方式 * JS向TS的转变。官方称TS是JS的超集。然后再编译器去掉类型和特有语法,生成纯粹的JavaScript代码。由于最终在浏览器中运行的是JavaScript,所以TypeScript并不依赖于浏览器的支持,也并不会带来兼容性问题。 * 因为JS是弱类型语言,声明变量使用的是var,而被声明的变量可以是任何类型,使用TS是因为其为强类型语言,在编译期间就能检测到变量类型的错误,IDE 智能提示,此举可以加快开发速度,提高代码的可读性。 > TypeScript官方文档[在线服务](https://www.tslang.cn/)。 #### angular-cli ###### 和官方快速起步文档给出的例子不同,生产中搭建Angular2的前端架构一般有三种选择(1.自己手动搭建目录依赖。2.Angular2 seed。Angular CLI),我们下面要使用Angular团队目前正在开发中的一个工具--Angular CLI。这是一个类似于React CLI和Ember CLI的命令行工具,用于快速构建Angular4的应用。 ###### 开始搭建,基础工具的安装:需要Node。 ###### 安装 Angular CLI (推荐使用高版本,本文使用版本为v1.3.0) windows : ```sh $ npm install -g angular-cli ``` macOS: ```sh $ sudo npm install -g angular-cli ``` ###### 之后你就可以在任何目录下构建你的angular项目了: ```sh $ ng new project_name ,project_name 是你的项目名; ``` - 注:使用ng命令行创建工程时还可以配置其他参数,如项目是使用css或是scss等,请自行搜索API。 ###### 创建工程 (下图就是创建的过程,此时在创建中,npm也在下载相关的包,耐心等待;从控制台中可以看到创建的内容): ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjls9zp6dlj20iw0fswgh.jpg) ###### 创建结束: ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlsae2dyxj20jm0flgns.jpg) ###### 创建后的工程结构: ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlsalz9m8j20890gemxq.jpg) ###### 工程结构熟悉一下: ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlsrglnbpj20wv0wzahw.jpg) - angular-cli.json 是angular-cli的配置文件 - 测试配置文件karma.conf.js - typescript的lint配置文件 - 端到端的测试配置文件protractor.conf.js - 导入es6模块的配置文件polyfills.ts - angular工程的main.ts引导启动文件 - 全局样式style.css - typescript配置文件ts.config.json - typescript的声明文件typings.d.ts - 以及生成了一个angular组建app.components相关的css,html,ts ###### 这些配置都是angular2的生产项目中需要配置的文件,angular-cli帮我们做了这么多事情,我们只用了一行命令 ###### 启动 ```sh $ cd project_name $ ng serve(or npm run start(可配置个人启动脚本如代理等)) ``` - 浏览器输入 http://localhost:4200/ 就可以看到app works! - 尝试的修改一下app.component.ts中的文字,可以看到热部署是否马上生效 ###### 创建其他模块代码如下: ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlsnpk34vj20c209kwfc.jpg) - 注: 创建component(ng generate component login)时可以看到其会自动在对应上级module中注入新建的component,快去试一试吧! > AngularCLI使用教程[在线服务](http://www.jianshu.com/p/cba3fa12f0a3)。 ###### 安装完以上这些工具,开发环境就部署好了,下面我们将开始Angular4的探险之旅。 ## TSLint ###### TSLint与JSLint一样定义了一组编码约定,这比ECMA定义的语言更为严格。这些编码约定汲取了多年来的丰富编码经验,并以一条年代久远的编程原则作为宗旨:能做并不意味着应该做。TSLint会对它认为有的编码实践加标志,另外还会指出哪些是明显的错误,从而促使你养成好的 TypeScript编码习惯。 #### ES6 ###### Angular2是面向未来的科技,要求浏览器支持ES6+,我们现在要尝试的话,需要加一些垫片来抹平当前浏览器与ES6的差异 ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjluwjfohaj20et08mdg9.jpg) - **systemjs** - 通用模块加载器,支持AMD、CommonJS、ES6等各种格式的JS模块加载 - **es6-module-loader** - ES6模块加载器,systemjs会自动加载这个模块 - **traceur** - ES6转码器,将ES6代码转换为当前浏览器支持的ES5代码。systemjs会自动加载 这个模块 ## angular4路由 #### angular4 路由 ###### 使用cli命令创建根路由模块 ng g cl app.router 或自己建一个路由配置文件 如:app/app.router.ts ```sh // app/app.router.ts // 将文件修改为 import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ // 以后在这里改动配置 { path: '**', pathMatch: 'full', redirectTo: '' } ]; // 将路由配置导出为 appRouting 以供调用, 子模块中的路由使用 forChild 而不是 forRoot export const appRouting = RouterModule.forRoot(routes); ``` ###### 在根模块中引入路由,为特性模块定义的路由在其模块中引入 ```sh // app/app.module.ts import { appRouting } from "./router/router.module" // @NgModule({ // imports: [ ... , appRouting // ... ``` ###### 路由配置 ```sh const routes: Routes = [ // path:路径 /news component:组件 { path: 'news', component: Newsomponent }, // path:路径 /detail/1 component:组件 { path: 'detail/:id', component: DetailComponent }, // 懒加载子模块, 子模块需要配置路由设置启动子组件 { path: 'other', loadChildren:"./other/other.module#otherModule" }, // 重定向 { path: '**', pathMatch: 'full', redirectTo: '' } ]; ``` - pathMatch?: string; 默认为前缀匹配 "prefix"; "full" 为完全匹配 - outlet?: string; 路由目标 - children?: Routes; 子路由的规则 ###### 加载路由:在根组件或当前组件的模板中 ```sh ``` ###### 另外,访问路由还可以通过routerLink指令等方式。 #### 页面划分路由结构(各自控制器只接管自己页面) #### 懒加载 ###### 当项目变得复杂庞大以后,如果所有页面都在一个模块里,就会出现首页加载慢的问题,因为首页就已经把整个项目加载进来了。所以,很有必要根据业务将不同的功能分模块,以便Angular2按需加载,提升用户体验。 ###### 通过loadChildren模块的方式进行懒加载。运用了懒加载的主路由 ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlvw7rh10j20py0jzjsl.jpg) ###### 运用了懒加载的次级路由 ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlvwxc3tej20v50hkq4a.jpg) ###### 底层路由 ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlwpyt09bj20nk09zt97.jpg) ###### 懒加载的好处能在项目打包的时候体现出来,其会将我们写好的代码分别打包成同的js文件,只有当我们访问到其路由的时候浏览器才会去加载这个js文件,这无疑为用户和服务器减小了一定的压力。 ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlw1d2lz9j20sd0fign9.jpg) ###### 注:由于目前项目还未完成所以这里提取出的js过小 #### 路由守卫 ###### 适用于后台管理等需要登录才能使用的模块 ###### 创建一个认证服务 ```sh // app/auth.service.ts import { Injectable } from '@angular/core'; import { CanActivate } from '@angular/router'; @Injectable() export class AuthService implements CanActivate { canActivate() { // 这里判断登录状态, 返回 true 或 false return true; } } ``` ###### 添加或修改路由配置 ```sh // app/app.router.ts // 增加 CanActivate import { CanActivate ... } from '@angular/router'; // 配置中增加 canActivate 如: { path: 'admin', canActivate:[AuthService] ... } ``` ###### 这样在每次访问这个路由地址时,代码会产生一个守护,相当于过滤器。 #### 依赖注入 ###### 依赖注入是重要的程序设计模式。Angular 有自己的依赖注入框架,离开了它,几乎没法构建 Angular 应用。它使用得非常广泛,以至于几乎每个人都会把它简称为 DI。 ###### 详见[官方文档](https://www.angular.cn/guide/dependency-injection) ## 项目目录结构 #### 模块化 组件化 ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlwbgl2r6j20da0orgmo.jpg) ###### 这里推荐的方法是使用路由嵌套,通过以上配置得到的对应的页面为: ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlwnznd3zj21hc0t0n0y.jpg) ###### 当页面仅输入localhost:4200时可得到如图页面路由地址,而每个component仅仅控制本html代码 #### http ###### 现在应用开发多为前后分离,前后端通讯则使用http的接口通过json进行交互。 #### 服务 Service ###### service,以下均可通过cli命令进行service构建(service应该只被运用于http调用的数据的交互)。 ```sh import {Injectable} from '@angular/core'; import { Http }from '@angular/http'; import * as api from './../api/Api'; import {Observable} from 'rxjs/Rx'; @Injectable() export class UserService { data:any; constructor(public http:Http) { this.http = http; } findAll():Observable { return this.http.get(api.findAll).map((res:any)=> { return res.json(); }); } } ``` ###### 组件HttpServiceComponent ```sh import {Component,OnInit} from '@angular/core'; import { UserService } from './../../service/UserService'; @Component({ selector: 'http-service', styles:[require('./HttpService.scss')], template: require('./HttpService.html'), providers: [UserService] }) export class HttpServiceComponent implements OnInit { admins:Object; data:Object; constructor(public userService:UserService) { this.userService = userService; } ngOnInit():void{ this.userService.findAll().subscribe((data:any) => { this.admins = data.adminUsers.content; console.log('in component : ',this.admins); }); console.log(' HttpServiceComponent ngOnInit :', 'enter'); } } ``` ###### 模板HttpService.Html ```sh ``` #### 自定义http封装 ###### 根据前后端协商构建客制化的http请求 ```sh export class DefHTTP { constructor() {} ... post(url, params?, errorText?: string): Observable { const fullURL = this.domain + url; return this.fullPost(fullURL, params, errorText); } ... } ``` ###### 具体请求可自行封装。 #### proxy ###### http代理,可以通过以下代码进行安装配置: ```sh $ npm install proxy --save ``` ###### 详细配置proxy.conf.json文件 ```sh { "/pro" : { "target": "http://256.256.256.256:8888" }, } ``` ###### 该配置可将本ip访问pro地址时转向traget地址。详见[官方文档](https://www.npmjs.com/package/proxy)。 #### RxJS ###### RxJS其处理异步逻辑,数据流,事件非常擅长。 但是其学习曲线相比Promise, EventEmitter陡峭了不少。 而且<>这篇文章也说:"由于RxJS的抽象程度很高,所以,可以用很简短代码表达很复杂的含义,这对开发人员的要求也会比较高,需要有比较强的归纳能力。 ###### (以下来自知乎...)很简单,懂点设计模式,特别是观察者模式。 ###### 然后再去学点函数式编程,学RxJS像玩一样(以上来自知乎...) ###### RxJS可以帮助我们实现响应式编程,处理异步的另一套解决方案(promise也是一套解决方案)。 ###### Observable 和Promise的区别: - Observable 可以处理多个事件,Promise则通常处理一个事件 - Observable 可以终止,Promise则不能 ###### 此为我觉得相对规范的RxJS写法,对应component.ts为: ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlxt0fv05j20o5044mx7.jpg) ###### 对应service为: ![](http://ww1.sinaimg.cn/large/737c07e1ly1fjlxv2g8bdj20zh09hjrs.jpg) ###### 详见[官方文档](http://reactivex.io/documentation/observable.html) ###### [RxJS 入门指引和初步应用](https://zhuanlan.zhihu.com/p/25383159) ###### 以及[通俗的方式理解RxJS](https://segmentfault.com/a/1190000008464065) ## 组件生命周期 ###### 正如其他框架的组件,Angular的组件也是有生命周期这个概念。在不同的阶段不同的场景下,可以调用不同的生命周期函数钩子(hook)。 - constructor:构造器函数,一般用于注入服务 - ngOnChanges:检测到输入数据变化,首次触发发生在ngOnInit前。注意对象的属性发生变化时监听不到 - ngOnInit:组件初始化,通常会设置一些初始值 - ngDoCheck:手动触发更新检查 - ngAfterContentInit:内容初始化到组件之后 - ngAfterContentChecked:内容变更检测之后 - ngAfterViewInit:视图 初始化之后 - ngAfterViewChecked:视图发生变化检测之后,这个可以用来保证用户视图的及时更新 - ngOnDestroy:组件注销时的清理工作,通常用于移除事件监听,退订可观察对象等 ###### 具体说明可以参考[这里](https://www.angular.cn/guide/lifecycle-hooks) ## 组件库 #### bootstrap(根据Angular使用方法为ngx-bootstrap) - 成熟的 Grid 栅格布局系统(列12等分) - 完备的样式组件库 - 强大的font-awesome图标库 - 自行体会 #### NG-ZORRO(基本不需要再使用bootstrap等其他组件库) ###### 作为八月底阿里发布的针对Angular2+的组件库,其涵盖了绝大部分的通用组件: - Grid 栅格(24 栅格系统),Layout 布局 - Components 涵盖面广满足绝大部分需求,此点甩大多数组件库八百条街 - 图标使用[阿里矢量图标库](http://www.iconfont.cn/plus),更好地客制化图标,能满足更多的需求并且减小代码体积 - 为了更小的代码压缩体积(基本上只需要这一个组件库就够了,别的组件基本不需要再引入),为了更好地完成代码(完善的API,完备的组件库),...,强烈建议使用 ## webpack ###### webpack:前端代码打包压缩模糊工具 ###### CLI自带webpack规则(但需要安装webpack(通过npm)),如果想自定义打包规则,可以自行创建webpack.config.js文件并调用。 #### prod ###### 打生产包时可以通过脚本构建不同的打包方式 ## 其他建议 - 尽量不适用jQuery或其他dom操作(影响性能) - ... ## 常用官方API或教程地址 - Angular 中文官方地址 [API](https://www.angular.cn/) - angular-education [使用Angular开发有用的材料列表](https://github.com/timjacobi/angular-education) - awesome-tutorials [Angular2.0从0到1](https://github.com/wpcfan/awesome-tutorials/blob/master/angular2/ng2-tut/README.md) - [@AngularClass a @OneSpeed-io 公司创建的精心策划的Angular资源列表 ](https://github.com/AngularClass/awesome-angular) - [Angular2系列教程](https://github.com/lewis617/angular2-tutorial) ## Angular4 前人总结 - [angularjs 1 和 2区别,这才是Angular2的灵魂!](http://www.jsout.com/page/420.html) - [Angular-使用Angular CLI快速搭建工程(一)](http://www.jianshu.com/p/cba3fa12f0a3) - [Angular-使用Angular CLI快速搭建工程(二)](http://www.jianshu.com/p/b8da7919dcf0) - [Angular中Input和Output用法及示例](http://blog.csdn.net/u014291497/article/details/60970792) - [Angular核心指令入门](http://cw.hubwiz.com/card/c/5599d367a164dd0d75929c76/1/2/1/) - [Angular4 路由设置相关](http://blog.csdn.net/u013589443/article/details/76026591) - [Angular4 简单入门笔记](http://blog.csdn.net/fen747042796/article/details/75152179) - [Angular2-除了自定义标签,你还可以这样配置组件的选择器](http://www.cnblogs.com/longhx/p/6959790.html) - [构建一个自定义 angular2 输入组件](https://segmentfault.com/a/1190000007603861) - [Angular 4 指令快速入门](https://segmentfault.com/a/1190000009674089) - [Angular 2 内置指令](https://segmentfault.com/a/1190000008626070) - [初步了解指令,及动手一步一步写个自定义指令](http://blog.csdn.net/crper/article/details/69400702) - [初步了解路由及使用](http://blog.csdn.net/crper/article/details/67639023) - [在 Angular2 中实现自定义校验指令(确认密码)的方法](http://www.jb51.net/article/104014.htm) - [慕课网-Angular2一小时快速入门](http://www.imooc.com/learn/789) - [Angular2 模块懒加载](https://www.pocketdigi.com/20170220/1568.html) - [Angular4.0 踩坑之路:探索子路由和懒加载](http://www.bubuko.com/infodetail-2274534.html) - [angular4 路由](https://segmentfault.com/a/1190000009357922) - ... ## Angular4 常见坑项 - [Angular 路由刷新404解决办法](http://www.jianshu.com/p/89a63ef5b2d9) - [angular-cli升级到1.0.0正式版后出现" Cannot find name 'require'"](https://www.w3cways.com/2111.html) - [angular2+ 如何在打包发布的时候清除console信息](http://blog.csdn.net/luo1055120207/article/details/76064115) - [解决:Angular-cli:执行ng-build --prod后,dist文件里无js文件、文件未压缩等问题](http://www.cnblogs.com/malvina/p/5982012.html) - [为什么我的webpack bundle.js和vendor.bundle.js这么大?](https://stackoverflow.com/questions/35408898/why-is-my-webpack-bundle-js-and-vendor-bundle-js-so-incredibly-big/35410342) - [angular2-aot-webpack 生产环境下编译angular2](http://www.cnblogs.com/ztwBlog/p/6209759.html) - 敬请补充... ## 贡献 ###### 站在巨人的肩膀上,才能够走得更远,感谢文章被引用的作者们。