Angular 基础教程(7.0)

课程亮点

  • 按照初学者的学习路线规划内容
  • 所有代码均采用 Angular 7.0 版本
  • 覆盖日常开发中使用频率最高的特性
  • To B、To C 型界面,移动端 PWA 全面覆盖
  • 附赠 3 个附录,对比 5.0、6.0、7.0 版本

读者反馈

《Angular 初学者快速上手教程》课程发布已有一年,期间收到了很多读者的留言,这里摘录几条,仅供参考。为了不打搅这些朋友,部分采用了匿名。

enter image description here

课程背景

本课程是 Angular 基础教程,目标是带领读者快速上手实战。课程以 3 个核心概念作为主线(组件、路由和模块)以及在业务开发过程中必须用到的特性(工具、指令、表单、RxJS、i18n、测试)来展开讲解。

除了这 3 个核心概念具有很强的关联性外,其他内容都是完全独立的,读者在用到的时候可以随时翻阅。注射器部分的内容稍微复杂一些,日常开发过程中用到的不多。

认真学完这门课程之后,将会深入理解新版本 Angular 的概念模型,具备使用 Angular 上手进行开发的基本能力。

作者介绍

大漠穷秋,10 年开发经验,其中 5 年后端、5 年前端。熟悉 Java 相关的技术体系:Spring MVC、MyBatis、Ehcache、ELK、MySQL 等。在前端技术方面尤其有深入的研究,先后使用并研究过 Flex、jQuery、Ext JS、Backbone、Bootstrap、Angular 等常见的前端技术体系。

2016 ~ 2017 年期间,担任 Angular Developer PM,专门帮助 Google Angular 团队在中国推广 Angular 框架。

出版了《Ext 江湖》一本图书,翻译出版了《ActionScript 3.0 游戏设计基础(第二版)》《用 AngularJS 开发下一代 Web 应用》《迈向 Angular 2》三本图书。

课程大纲

enter image description here

* 实际更新文章题目可能与框架略有出入

课程内容

开篇词:为什么会写 Angular 这门课

有的读者可能会问:Angular 相关的文章到处都有,我为什么要来学习这门课?

这是一个非常好的问题,说明读者对阅读内容有质量要求。

如果是我,我也会有这样的疑惑。

整体上说,这门课的内容有以下特色。

最近 5 年我一直在“玩”前端方面的东西,比如 jQuery、SVG、Ext JS、Adobe Flex、Angular;尤其在 2016 年,这一整年的时间我代表 Angular 项目组在中国进行技术推广。因此,我会按照初学者一般的学习过程,用我自己的语言一步一步进行讲解

在这 5 年里,我在超过 50 家企业、开源组织、大学里面进行了大量演讲,在网络上发布了大量的视频和文章。在到处奔波的过程中,认识了很多人,有经验丰富的后端开发者、也有新入行的初学者,他们跟我说过很多自己的困惑,我会把常见的一些疑问融入在内容里面

我也会扫平日常开发中常见的坑,这些坑大部分都是开发者们反馈给我的,或者是到我这里吐槽过的。举几个典型的例子:

  • 很多开发者到我这里来抱怨说,在 Windows 平台上安装 @angular/cli 会报很多 error,那是因为 @angular/cli 在 Windows 平台上面依赖 Python 和 Visual Studio 环境,而很多开发者的机器上并没有安装这些东西。为什么要依赖这些环境?因为某些 npm 包需要在你本地进行源码编译。
  • node-sass 模块被墙的问题,强烈推荐使用 cnpm 进行安装(点击这里跳转到安装地址),可以非常有效地避免撞墙。
  • 一些开发者来抱怨说 @angular/cli 在打包的时候加上 --prod 参数会报错,无法编译。这是一个很常见的问题,因为 @angular/cli 最新的版本经常会有 bug,只要在项目的 package.json 里面降低一个小版本号就 OK 了。另外,加 --prod 参数之后,编译器会进行更加严格的检查,如果存在无用的组件或者配置错误,则编译过不去。
  • @angular/cli 默认生成的 karma.conf.js 配置文件里面采用了一个有 bug 的 HTML 报告生成器,导致 ng test 运行报错,我们需要把这个 reporter 改成 mocha(摩卡),具体的配置和实例请参考“第10课:自动化测试”中的讲解。
  • 还有的开发者说,本地开发的时候运行得很好,上线之后所有请求 404。这也是一个常见的坑,因为你需要给 Web 容器配置一下处理 HTTP 请求的规则,把前端路由扔回去交给 Angular 处理,可点击这里查看具体的情况

诸如此类的坑还有不少,我都是一个一个踩过来的。当然,我相信读者也能踩过来,但是从节约时间的角度来看,跟着我的思路走一遍岂不是更快?

这门课全部聚焦在使用层面上,覆盖日常开发中使用频率最高的特性,除非迫不得已,尽量不扯原理。长期以来,我发现有很多读者的学习方式存在误区,比如,有一些人上来就去研究“变更检测”的原理,还有 RxJS 的原理,这种方式除了打击你自己的自信心之外得不到任何好处。因为你迟早会发现,在计算机领域,任何东西研究到最底层都和“算法”、“数据结构”、“设计模式”有关。

据我所知,很多读者平时并没有去研究这些内容的基础知识,因此,我推荐采用更加务实一点的方案,首先学会如何使用,等用熟练了,有时间、有闲情的时候再去研究那些底层的原理。设计发动机很难,但是学会开车并不难,对吧?所以我写这门课的目标很简单,就是带你学会开车,而不是教你设计发动机。

这门课非常看重“概念模型”(Mental Model)的构建。我发现,很多开发者已经做过非常多的项目了,但是当你跟他聊的时候,很快就会发现他并没有掌握这门框架的精髓。打几个比方:

  • 当有人提到 Spring 的时候,你的大脑里面第一个想到的一定是 DI、IoC、AOP 等这些核心概念;
  • 当有人提到 Hibernate、MyBatis、JPA 的时候,你的大脑里面立即会浮现出 ORM 等概念;
  • 当有人提到 React 的时候,你想到的应该是 VDOM、JSX;
  • 当有人提到 jQuery 的时候,你首先想到的应该是 $,对吧?

因此,可以看到,任何一个成功的框架都有自己独创的“概念模型”,或者叫“核心价值”也可以,这是框架本身存在的价值,这些核心概念是掌握这个框架应该紧扣的主线,而不是上来就陷入到茫茫的技术细节里面去。

课程里面涉及到的例子总数量大约有 300 个,有少量例子来自官方文档(大约 5 个),其他的例子都是我自己一点一点手动敲出来的。我把这些例子分成了 10 个开源项目,它们互相独立,方便读者进行参考和练习。这些教学用的开源项目本身是免费的,已放在了本课的末尾。

Angular 的概念模型

既然如此,问题就来了,新版本的 Angular 的核心概念是什么呢?

非常简单,一切都是围绕着“组件”(Component)的概念展开的。

86a9de10-e25f-11e8-aea1-e3c6bbbc3251

  • Component(组件)是整个框架的核心,也是终极目标。“组件化”的意义有 2 个:一是分治,因为有了组件之后,我们可以把各种逻辑封装在组件内部,避免混在一起;二是复用,封装成组件之后不仅可以在项目内部复用,而且还可以沉淀下来跨项目复用。
  • NgModule(模块)是组织业务代码的利器,按照自己的业务场景,把组件、服务、路由打包到模块里面,形成一个个的积木块,然后再用这些积木块来搭建出高楼大厦。
  • Router(路由)的角色也非常重要,它有 3 个重要的作用:一是封装浏览器的 History 操作;二是负责异步模块的加载;三是管理组件的生命周期。

因此,在这门课程里面,Component、NgModule、Router 加起来会占据绝大部分的篇幅,而一些琐碎的小特性会被忽略掉。我相信,读者只要紧扣“组件化”这个主线,就能站在一个很高的角度去统摄全局,从而掌握到这个框架的精髓。

适合阅读的人群

本课程内容适合以下人群阅读:

  • Angular 新版本的初学者
  • 有 AngularJS 经验的开发者
  • 希望了解 Angular 新版本核心特性的开发者
  • Java 和 .NET 开发者,会发现 Angular 里面的很多概念和做法非常适合已经掌握了那些概念模型的开发者,学起来会非常快

特别注意:这门课程不是前端入门读物,读者至少需要会一门编程语言,无论前端还是后端都可以,如果你曾经使用过一门前端框架,那就更好了。

集中回答一些常见的问题

浏览器兼容性

关于 Angular 的浏览器兼容性,请看下图:

enter image description here

有一些国内的开发者会来争论兼容 IE 8 的问题,请看下面的两个事实。

  • 第一个事实:截至 2018 年 10 月底,Chrome 的全球市场份额已经接近 60.6%,Safari 占 14.85%,Firefox 占 5.01%,加起来已经占到 80.46%,真的没有那么多人用 IE 了。

enter image description here

点击这里查看数据来源

  • 第二个事实:天猫已经于 2016 年 4 月宣布放弃支持 IE 6、7、8 了。而根据百度流量研究院的统计,IE 8 目前的整体市场份额已经下降到了 9.31%。

enter image description here

点击这里查看数据来源

读者完全可以用上面的两点事实去说服客户,不值得为了这么少的市场份额付出那么多的研发和维护成本。

命名约定

老版本使用 AngularJS 指代,所有新版本都叫做 Angular。原因很好理解,因为老版本是用 JS 开发的,所以带一个 JS 后缀,而新版本是基于 TypeScript 开发的,带 JS 后缀不合适。

关于 TypeScript

这门课程不会单独讲 TypeScript,正如我一直强调的:TypeScript 不难,JavaScript 才难。你跟着我的思路,TypeScript 绝对不会成为你学习 Angular 的障碍。相反,一旦你写代码熟练了之后,TypeScript 可以非常有效地提升编码效率和程序可读性。

关于 Angular 的版本

官方的版本发布计划是:

  • 每 6 个月发布一个主版本(第一位版本号,主版本)
  • 每个主版本发布 1 ~ 3 个小版本(第二位版本号,Feature 版本号)
  • 每周发布一个补丁版本(第三位版本号,Hotfix 版本号)

根据官方的解释,Angular 2.0 之后会保证向下兼容,只有在升级主版本的时候才会做一些 breaking change。因此,这门课程不再强调版本号,涉及到的所有实例代码都已经升级到了当前最新的 7.x 版本(2018-11)。

本课程划分 3 大部分,共计 46 篇(含导读)。

  • 第一部分(第 01 课 ~ 第 10 课,共 32 篇)的内容将围绕组件、模块、路由三大概念,兼顾服务、RxJS、表单、i18n 等小工具,全面解释了 Angular 的基本用法。
  • 第二部分(第 11 课,共 8 篇)的内容将专门解释依赖注入,这是 Angular 比较有特色的内容,这部分的内容比较有深度,虽然在日常开发中使用不多,但是理解它能够更加深入理解 Angular。
  • 第三部分(第 12 课 ~ 附录 3,共 5 篇)的内容将讲解实例项目 OpenWMS、一些参考资源及三个附录。

本课程对应的所有示例项目列表如下:

最后是那一句套话:水平有限,错漏难免,欢迎指正。

第01课:搭建开发环境

本课的主要内容:

  • Node.js
  • Angular CLI
  • 创建第一个项目
  • 一些常见的坑
  • VS Code
  • webpack-bundle-analyzer

Node.js

2009 年,Node.js 发布了第一个版本,标志着前端开发正式告别了刀耕火种的原始状态,开始进入工业化时代。

在 Node.js 出现之前,前端开发领域有很多事情我们是做不到的,比如:

  • JS 代码的合并、压缩、混淆
  • CSS 预处理
  • 前端自动化测试

而这一切在 Node.js 出现之后都得到了很好的解决。

  • 对 JS 代码的预处理经历了 Grunt、Gulp 的短暂辉煌之后,终于在 Webpack 这里形成了事实标准的局面。
  • CSS 的预处理也从 Less 发展到了 Sass 等。
  • 自动化测试一直是前端开发中的一个巨大痛点,由于前端在运行时严重依赖浏览器环境,导致我们一直无法像测试后端代码那样可以去编写测试用例。Node.js 出现之后,终于有了像 Karma + Jasmine 这样的单元测试组合,也有了基于 WebDriverJS 这样的可以和浏览器进行通讯的集成测试神器。

就前端开发目前整体的状态来说,无论使用什么框架,Node.js、Webpack、Sass、Karma + Jasmine、WebDriverJS 这个组合是无论如何绕不过去的。

Angular CLI

4b1f3900-e3c5-11e8-a1c4-731a3e37324c

在开发 Angular 应用的时候,当然也离不开大量基于 Node.js 的工具,我们需要 TypeScript Compiler、Webpack、Karma、Jasmine、Protracter 等模块。

有相关经验的开发者都知道,自己从头开始去搭建一套基于 Webpack 的开发环境是一件非常麻烦的事情,很多初学者在搭建环境这一步就消耗了过多的精力,导致学习热情受到了沉重的打击。

当团队规模比较大的时候,在每个人的机器上配置环境需要消耗大量的时间。有一些团队为了避开这个坑,利用 Docker 来做开发环境的同步和版本升级,看起来也是一个非常不错的方案。

Angular 项目组从一开始就注意到了这个问题,所以有了 Angular CLI 这个神器,它的底层基于 Webpack,集成了以上提到的所有 Node.js 组件,你只要安装好 Angular CLI 就够了,不需要自己从头一步一步安装那些 Node.js 插件。

当然,在安装 Angular CLI 之前需要先把 Node.js 安装好,请到官方网站(点击这里跳转到官方网站) 下载安装包,安装过程和普通软件没有区别。安装好 Node.js 之后就可以安装 Angular CLI 了,由于 npm 会自动访问海外的服务器,因而强烈推荐使用 cnpm 进行安装:

npm i -g cnpm --registry=https://registry.npm.taobao.orgcnpm i -g @angular/cli

cnpm 是淘宝发布的一款工具,会自动把 npm 上面的所有包定时同步到国内的服务器上来,cnpm 本身也是一款 Node.js 模块。

Angular CLI 安装成功之后终端里面将会多出一个名叫 ng 的命令,敲下 ng,将会显示完整的帮助文档:

enter image description here

创建第一个项目

我们来创建第一个入门项目 HelloAngular,请在终端里面运行如下命令:

ng new HelloAngular

@angular/cli 将会自动帮你把目录结构创建好,并且会自动生成一些模板化的文件,就像这样:

a23847e0-e3c5-11e8-a1c4-731a3e37324c

请特别注意:@angular/cli 在自动生成好项目骨架之后,会立即自动使用 npm 来安装所依赖的 Node 模块,因此这里我们要用组合键 Ctrl + C 终止掉它,然后自己进入项目的根目录,使用 cnpm 命令来进行安装。

enter image description here

安装完成之后,使用 ng serve 命令启动项目:

enter image description here

打开浏览器,访问默认的 4200 端口,若看到以下界面就说明环境 OK 了:

cb88e910-e3c5-11e8-bfed-8d6b896efba7

请注意以下几点:

  • 这里是 serve,不是 server,我看到一些初学者经常坑在这个地方。
  • 如果需要修改端口号,可以用 ng serve --port **** 命令来进行指定。
  • ng serve --open 可以自动打开默认的浏览器。
  • 如果想让编译的包更小一些,可以使用 ng serve --prod,@angular/cli 会启用 TreeShaking 特性,加了参数之后编译的过程也会慢很多。因此,在正常的开发过程里面请不要加 --prod 参数。
  • ng serve 是在内存里面生成项目,如果你想看到项目编译之后的产物,请运行 ng build。构建最终产品版本可以加参数,ng build --prod。

ng 提供了很多非常好用的工具,除了可以利用 ng new 命令来自动创建项目骨架之外,它还可以帮助我们创建 Angular 里面所涉及到的很多模块,最常用的有以下几个。

  • 自动创建组件(ng generate component MyComponentng g c MyComponent),创建组件的时候也可以带路径,如 ng generate component mydir / MyComponent
  • 自动创建指令:ng g d MyDirective。
  • 自动创建服务:ng g s MyService。
  • 构建项目:ng build,如果想构建最终的产品版本,可以用 ng build --prod 命令。

更多的命令和参数请在终端里面输入 ng 命令仔细查看,尽快熟悉这些工具可以非常显著地提升编码效率。

一些常见的坑

@angular/cli 这种“全家桶”式的设计带来了很大的方便,同时也有一些读者不太喜欢,因为很多底层的东西被屏蔽掉了,开发者不能天马行空的自由发挥。比如,@angular/cli 把底层 Webpack 的配置文件屏蔽掉了,很多喜欢自己手动配 Webpack 的开发者就会感到很不爽。

对于国内的开发者来说,上面这些其实不是最重要的,国内开发者碰到的坑主要是由以下两点问题引起的:

  • 网络问题,比如 node-sass 这个模块很有可能就装不上,原因你懂的;
  • 开发环境导致的问题,国内使用 Windows 平台的开发者比例依然巨大,而 @angular/cli 在 Windows 平台上有一些非常恶心的依赖,比如它需要依赖 Python 环境、Visual Studio 环境。

因此,如果你的开发平台是 Windows,请特别注意以下几点。

  • 如果你知道如何给 npm 配置代理,也知道如何翻墙,请首选 npm 来安装 Angular CLI。否则,请使用 cnpm 来安装 Angular CLI,原因有三:
    • cnpm 的缓存服务器在国内,装东西的速度会快很多;
    • 用 cnpm 可以帮你避开某些模块装不上的问题,因为它在服务器上面做了缓存;
    • cnpm 还把一些包都预编译好了缓存在服务端,比如 node-sass,使用 cnpm 不需要在本地进行源码编译,因此你的机器上可以没有那一大堆麻烦的环境。
  • 如果安装失败,请手动把 node_modules 目录删掉重试一遍,全局的 @angular/cli 也需要删掉重装,cnpm uninstall -g @angular/cli。
  • 如果 node_modules 删不掉,报出路径过长等之类的错误,请尝试用一些文件粉碎机之类的工具强行删除,这是 npm 的锅,与 Angular 无关。
  • 最新版本的 Angular CLI 经常会有 bug,尤其是在 Windows 平台上面,请不要追新版本太紧,如果发现了莫名其妙的问题,请尝试降低一个主版本试试。这一点非常重要,很多初学者会非常困惑,代码什么都没改,就升级了一下环境,然后会有各种编译报错。如果你愿意,去官方 (点击这里跳转到官网) 提 issue 是个很不错的办法。
  • 对于 MAC 用户或者 *nix 用户,请特别注意权限问题,命令前面最好加上 sudo,保证有 root 权限。
  • 无论你用什么开发环境,安装的过程中请仔细看 log,很多读者没有看 log 的习惯,报错的时候直接懵掉,根本不知道发生了什么。

VS Code

053306a0-e3c6-11e8-8e04-b95633cc2286

如你所知,一直以来,前端开发领域并没有一款特别好用的开发和调试工具。

  • WebStorm 很强大,但是吃资源很严重。
  • Sublime Text 插件很多,可惜要收费,而国内的企业还没有养成花钱购买开发工具的习惯。
  • Chrome 的开发者工具很好用,但是要直接调试 TypeScript 很麻烦。

因此,Visual Studio Code(VS Code)才会呈现出爆炸性增长的趋势,它是微软开发的一款前端编辑器,完全开源免费。VS Code 底层是 Electron,界面本身是用 TypeScript 开发的。对于 Angular 开发者来说,当然要强烈推荐 VS Code。最值得一提的是,从 1.14 开始,可以直接在 VS Code 里面调试 TypeScript 代码。

环境配置

  • 确保 Chrome 安装在默认位置
  • 确保 VS Code 里面安装了 Debugger for Chrome 这个插件
  • 把 Angular CLI 安装到全局空间 npm install -g @angular/cli,国内用户请使用 cnpm 进行安装。注意,最好升级到最新版本的 Angular CLI,避免版本兼容问题。
  • 用 @angular/cli 创建新项目 ng new my-app ,本来就已经用 @angular/cli 创建的项目请忽略这一步,继续往下走,因为只要是 CLI 创建的项目,后面的步骤都是有效的。
  • 用 VS Code 打开项目,进入项目根目录。

配置 launch.json

17a9e4c0-e3c6-11e8-a1c4-731a3e37324c

请参照以上步骤打开 launch.json 配置文件。

enter image description here

请把本地 launch.json 文件里面的内容改成这样:

{    "version": "0.2.0",    "configurations": [        {            "type": "chrome",            "request": "launch",            "name": "Chrome",            "url": "http://localhost:4200",            "webRoot": "${workspaceRoot}"        }    ]}

开始 Debug

在 app.component.ts 的构造函数里面打个断点,我本地是这样打断点的:

enter image description here

打开终端,进入项目根目录,运行 ng serve 启动项目,然后从 VS Code 的 debug 界面启动 Chrome

3fe915f0-e3c6-11e8-a397-15a3bf78ee55

注意,可能需要 F5 刷新一下 Chrome 才能进入断点!

enter image description here

市场上有大量的 VSCode 插件可供选择,比如彩虹缩进、智能提示、自动补齐标签之类的功能,将会大幅度提升开发效率,这里列出了 10 款我自己日常使用的插件供你参考,点击这里查看详情

webpack-bundle-analyzer

在真实的业务项目中,我们会用到大量的第三方开源组件,如图形库 ECharts、组件库 PrimeNG 等。

有很多开发者在引入这些组件库之后,没有注意到体积问题,导致最终编译出来的包体积过大,比如我自己的 OpenWMS 项目,以下是 build 出来的体积:

enter image description here

用 webpack-bundle-analyzer 分析之后可以看到各个模块在编译之后所占的体积:

enter image description here

可以看到,主要是因为 ECharts 和 PrimeNG 占的体积比较大,建议在使用的时候做一下异步,用不到的组件不要一股脑全部导入进来。

webpack-bundle-analyzer 的用法和详细文档 请点击这里查看

小结

目前,无论使用什么前端框架,都必然要使用到各种 Node.js 工具,Angular 也不例外。

与其他框架不同,Angular 从一开始走的就是“全家桶”式的设计思路,Angular CLI 这款工具里面集成了日常开发需要使用的所有 Node 模块,使用 @angular/cli 可以大幅度降低搭建开发环境的难度。

第2-1课:组件概述

fb1852c0-e3d3-11e8-a1c4-731a3e37324c

几乎所有前端框架都在玩“组件化”,而且最近都不约而同地选择了“标签化”这种思路,Angular 也不例外。

对于新版本的 Angular 来说,一切都是围绕着“组件化”来展开的,组件是 Angular 的核心概念模型。

以下是一个最简单的 Angular 组件定义。

09c6de40-e3d4-11e8-a397-15a3bf78ee55

  • @Component:这是一个 Decorator(装饰器),其作用类似于 Java 里面的 Annotation(注解)。Decorator 这个特性目前处于 Stage 2(草稿)状态,还不是 ECMA 的正式规范,请点击这里查看具体详情
  • selector:组件的标签名,外部使用者可以这样来使用以上组件,<app-root>。默认情况下,ng 命令生成出来的组件都会带上一个 app 前缀,如果你不喜欢,可以在 angular-cli.json 里面修改 prefix 配置项,设置为空字符串将会不带任何前缀。
  • templateUrl:引用外部 HTML 模板。如果你想直接编写内联模板,可以使用 template,支持 ES 6 引入的“模板字符串”写法,请点击这里查看具体详情
  • styleUrls:引用外部 CSS 样式文件,这是一个数组,也就意味着可以引用多份 CSS 文件。
  • export class AppComponent:这是 ES 6 里面引入的模块和 class 定义方式。

完整的实例代码请点击这里下载

第2-2课:把 CSS 预编译器改成 Sass
第2-3课:组件模板
第2-4课:组件间通讯
第2-5课:生命周期钩子
第2-6课:组件动效
第2-7课:动态组件
第2-8课:ShadowDOM 组件
第2-9课:内容投影
第2-10课:@ContentChild & @ContentChildren
第2-11课:@ViewChild & @ViewChildren
第2-12课:与 Polymer 封装组件的方式简单对比
第2-13课:封装并发布组件库
第3-1课:指令简介
第3-2课:自定义指令
第3-3课:直接在组件里面操作 DOM
第04课:模块 @NgModule
第5-1课:路由概述
第5-2课:路由基本用法
第5-3课:模块预加载
第5-4课:路由守卫
第5-5课:多重出口
第6-1课:表单快速上手
第6-2课:双向数据绑定
第6-3课:表单校验
第6-4课:模型驱动型表单
第6-5课:动态表单
第07课:服务
第08课:RxJS 快速上手
第09课:国际化
第10课:自动化测试
第11-1课:注射器树基础知识
第11-2课:Angular 依赖注入的基本玩法(1)
第11-2课:@Injectable & @Inject(2)
第11-3课:@Self
第11-4课:@Optional
第11-5课:@SkipSelf
第11-6课:@Host
第11-7课:手动操作注射器实例
第12课:综合实例 OpenWMS 介绍
第13课:参考资源
附录 1:Angular 5.0 引入的新特性
附录 2:Angular 6.0 引入的新特性
附录 3:Angular 7.0 引入的新特性

阅读全文: http://gitbook.cn/gitchat/column/5bebdaf22c33167c317cc285

猜你喜欢

转载自blog.csdn.net/valada/article/details/84537383
今日推荐