简述Angular 5 快速入门


Posted in Javascript onNovember 04, 2017

一、概述

尽管被称为Angular5,实际上它只是这个诞生于2012年的前端框架的的第四个版本:

简述Angular 5 快速入门
angular history

看起来差不多半年就发布一个新版本,不过实际上从重写的版本2开始,开发接口与核心思想就稳定下来了,并基本保持着与前序版本的兼容性。

在5这个新的版本中,Angular团队将改进重点放在以下特性方面:

  1. 更易于构建渐进式Web应用 —— __P__rogressive __W__eb __A__pp
  2. 使用构建优化器剔除无用代码,以获得更小的应用、更快的网络加载时间
  3. 使物化设计组件兼容服务端渲染

PWA是Google提出的一个标准,旨在让Web应用在移动终端上获得媲美原生应用的用户体验。一个PWA应用主要利用Service Worker和浏览器缓存来提省交互体验,它不仅可以直接部署在手机桌面,而且可以离线应用:

简述Angular 5 快速入门

pwa

二、引入angular环境

Angular推荐使用TypeScript来开发应用,这要求使用一个在线编译器(JIT)实时编译代码,或者在开发期采用预编译器(AOT)提前编译代码。

为了避免这个繁琐的过程影响对Angular框架本质的思考,我们将这些必需品进行了必要的配置和打包,以便适应在线编写和实验。现在只需要引入一个库a5-loader就可以了。

下图是库的构成示意,其中的蓝色部件均打包在库中:

简述Angular 5 快速入门

a5-loader

你可能注意到Angular框架并不是蓝色的。的确,我们没有把它打包在a5-loader中,而是让模块加载器(SystemJS)根据应用的需要自动加载。这么做的目的,是为了让应用代码,和后续课程中采用的后端构建方法保持一致。

如果你对这个库有兴趣,可以访问github上的 http://github.com/hubwiz/a5-loader 仓库。

三、创建Angular组件

Angular是面向组件的前端开发框架。如果你从事过C/S图形化应用的开发,应该知道组件这个词的含义。基本上,组件代表着一些具有图形界面,并且具有内在逻辑能力的程序单元。下图列出了三种用于实现乒乓切换的组件:

简述Angular 5 快速入门

component sample

组件提供了很好的复用性,在一堆组件的基础上,我们使用简单的胶水代码就可以实现相当复杂的交互功能。

现在让我们来创建Angular组件,代码相当简单:

@Component({ selector: "ez-app", template: `<h1>Hello,angular5</h1>`})class EzComp{}

在Angular框架中,组件就是指一个应用了Component装饰器的类。Component装饰器的作用,就是为被装饰的类附加元数据信息:

简述Angular 5 快速入门

annotations

Angular框架对应用进行编译引导时,将使用这些元数据构造视图。其中的两个元数据非常重要:

  1. selector:组件宿主元素的CSS选择符,声明了组件在DOM树中的渲染锚点
  2. template:组件的模板,框架将以这个模板为蓝图构建视图

四、创建Angular模块

Angular框架的核心是组件化,同时它的设计目标是适应大型应用的开发。因此,在应用开发中引入了模块(NgModule)的概念来组织不同的组件(及服务),一个Angular应用至少需要创建一个模块。

为了区别于JavaScript语言本身的模块概念,在本课程中将使用NG模块来表示一个Angular模块。

类似于组件,NG模块就是一个应用了NgModule装饰器的类。例如,下面的代码创建了一个NG模块EzModule:

@NgModule({
 imports: [ BrowserModule ],
 declarations: [ EzComp ],
 bootstrap: [ EzComp ]
})
class EzModule{}

同样,NgModule装饰器用来给被装饰的类附加模块元数据,可以查看被装饰类的__annotations__属性来观察这一结果:

简述Angular 5 快速入门

ngmodule annotations

NgModule装饰器声明了一些关键的元数据,来通知框架需要载入哪些NG模块、编译哪些组件以及启动引导哪些组件:

  1. imports: 需要引入的外部NG模块
  2. declarations:本模块创建的组件,加入到这个元数据中的组件才会被编译
  3. bootstrap:声明启动引导哪个组件,必须是编译过的组件

需要强调的是,bootstrap元数据声明的组件必须是编译过的组件:它要么属于使用imports元数据引入的外部NG模块,要么是已经在declarations元数据中声明的本地组件。

NG模块BrowserModule定义于包@angular/platform-browser,它是Angular跨平台战略的重要组成部分。BrowserModule封装了浏览器平台下的核心功能实现,与之对应的其他平台实现还有:

  1. ServerModule:服务端实现
  2. WorkerAppModule:WebWorker实现

通常情况下开发Web应用时,我们都需要引入BrowserModule这一NG模块。

五、启动Angular应用

前面课程中,我们已经创建了一个组件和一个NG模块,不过似乎只是定义了一堆的元数据,几乎没有写太多有价值的代码。
但这就是Angular框架的一个特点:声明式开发。这些元数据是用来向框架声明如何引导启动应用程序的重要信息。

启动代码很简单,引入platformBrowserDynamic()工厂函数、创建平台实例、启动指定模块:

import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"
const pref = platformBrowserDynamic()
pref.bootstrapModule(EzModule)

√ 平台对象:PlatformRef

platformBrowserDynamic()函数返回一个PlatformRef对象(Angular对平台的抽象),这个函数最重要的作用,在于其内部创建了一个即时(__J__ust __I__n __T__ime)编译器,可以在线实时编译NG模块和组件,这也是它被称为动态(Dynamic)的原因:

简述Angular 5 快速入门

dynamic bootstrap

平台对象的bootstrapModule()方法用来启动指定的NG模块,启动的绝大部分工作,在于利用JIT编译器编译NG模块和组件,当这些编译工作都完成后,则根据启动模块的bootstrap元信息,渲染指定的组件。

六、为什么这么复杂?

可能你已经感觉有点复杂了:只是为了写一个Hello,World,就要写这么多代码。

事实上这些复杂性是随着Angular的发展逐步引入的,从好的一方面说,是提供给开发者的可选项逐渐增多了,适用场景变多了。

比如,在Angular2正式版之前,都没有NG模块的概念,你只要写一个组件就可以直接启动应用了。Angular团队的预期应用场景是大规模前端应用开发,因此显式的NG模块声明要求也是容易理解的。不过即使是小型的应用,由于可以只使用一个NG模块,因此这一点的复杂性增加倒也不多,只是增加了学习和运用这个新概念的成本。

另一个显而易见的复杂性,在于多平台战略的引入。Angular希望让应用可以跨越浏览器、服务器等多个平台(基本)直接运行。因此免不了抽象一个中间层出来,我们需要在应用中显式地选择相应的平台实现模块:

简述Angular 5 快速入门

multiple platform

第三个复杂性来源于对预编译(AOT:Ahead Of Time)的支持。在早期,Angular只有即时编译(JIT:Just In Time),也就是说应用代码是在运行时编译的。即时编译的第一个问题是在应用中需要打包编译器代码,这增加了最终发布的应用代码的
大小;另一个问题在于编译需要时间,这增加了用户打开应用的等待时间。因此现在的Angular是同时支持JIT和AOT的,但启动JIT编译的应用,和启动AOT编译的应用,在目前需要显式地进行选择:

简述Angular 5 快速入门

aot vs. jit

对于Angular而言,编译将入口NG模块定义转换为NG模块工厂(NgModuleFactory)。对于JIT而言,这一步是隐含在bootstrapModule()中的。而对于AOT而言,生成模块工厂就结束了,应用启动时使用bootstrapModuleFactory()调用生成的模块工厂即可。

尽管AOT编译通常在构建阶段运用,我们可以在浏览器里模拟这个分两步的过程。

七、理解Angular的初衷

除了框架本身的功能强大导致的复杂性,Angular的另一个复杂性来源在于其高度封装的声明式API,让开发者难以揣摩、洞察框架的实现机制,因此使用起来就很心虚,一旦出现问题则难以分析排错:

简述Angular 5 快速入门

angular error

不能把Angular当作黑盒来使用。

一方面原因在于,Angular是以其声明式的模板语法为核心提供API开发接口的,开发者书写的模板,经过框架相当复杂的编译处理,才渲染出最终的视图对象。如果不尝试了解从模板到视图对象这个过程究竟发生了什么,我相信你始终会有一种失控的感觉。

另一方面原因在于,Angular是一个框架,它搭好了应用程序的架子,留了一些空隙让开发者填充。如果不尽可能地了解框架的运行机制,很难充分地利用好框架。

开发Angular的出发点,是为了实现用HTML来编写用户界面,想想一个静态网页有多容易开发,你就知道这是多么好的想法:

简述Angular 5 快速入门

html challenge

原生HTML的问题在于,首先它需要借助于JavaScript才能实现过得去的用户交互,其次它只有那么多标签可用,难以担当开发用户界面的大任。

既然浏览器不能直接解释<ez-gauge>这样的标签,Angular团队就引入了编译器的概念:
在送给浏览器之前,先把有扩展标签的HTML翻译成浏览器支持的原生HTML:

简述Angular 5 快速入门

html compiler

写在文末:相信很多学习angular的同学都看过我写的内容,想来或多或少的应该有些帮助。希望这个内容能给大家带来更多的帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery实战之品牌展示列表效果
Apr 10 Javascript
可兼容IE的获取及设置cookie的jquery.cookie函数方法
Sep 02 Javascript
JavaScript避免内存泄露及内存管理技巧
Sep 05 Javascript
JavaScript中的small()方法使用详解
Jun 08 Javascript
基于JavaScript短信验证码如何实现
Jan 24 Javascript
全面接触神奇的Bootstrap导航条实战篇
Aug 01 Javascript
使用jQuery Ajax 请求webservice来实现更简练的Ajax
Aug 04 Javascript
AngularJS入门教程之路由机制ngRoute实例分析
Dec 13 Javascript
BootStrap实现轮播图效果(收藏)
Dec 30 Javascript
JS实现的找零张数最小问题示例
Nov 28 Javascript
JavaScript实现简单的隐藏式侧边栏功能示例
Aug 31 Javascript
vue实现点击按钮下载文件功能
Oct 11 Javascript
vue2.0在table中实现全选和反选的示例代码
Nov 04 #Javascript
vue中使用localstorage来存储页面信息
Nov 04 #Javascript
javascript+jQuery实现360开机时间显示效果
Nov 03 #jQuery
原生JavaScrpit中异步请求Ajax实现方法
Nov 03 #Javascript
使用 Javascript 实现浏览器推送提醒功能的示例
Nov 03 #Javascript
Angular4绑定html内容出现警告的处理方法
Nov 03 #Javascript
关于Vue背景图打包之后访问路径错误问题的解决
Nov 03 #Javascript
You might like
用PHP调用Oracle存储过程
2006/10/09 PHP
PHP 可阅读随机字符串代码
2010/05/26 PHP
Apache2中实现多网站域名绑定的实现方法
2011/06/01 PHP
PHP中如何调用webservice的实例参考
2013/04/25 PHP
PHP中$_SERVER的详细参数与说明介绍
2013/10/26 PHP
codeigniter上传图片不能正确识别图片类型问题解决方法
2014/07/25 PHP
JavaScript使用prototype定义对象类型
2007/02/07 Javascript
JavaScript中奇葩的假值示例应用
2014/03/11 Javascript
AngularJS ng-blur 指令详解及简单实例
2016/07/30 Javascript
jQuery实现表格奇偶行显示不同背景色 就这么简单
2017/03/13 Javascript
Vuex 在Vue 组件中获得Vuex 状态state的方法
2018/08/27 Javascript
vue 配置多页面应用的示例代码
2018/10/22 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
Vue中Axios从远程/后台读取数据
2019/01/21 Javascript
小程序云开发获取不到数据库记录的解决方法
2019/05/18 Javascript
简单了解vue中的v-if和v-show的区别
2019/10/08 Javascript
vue实现登录功能
2020/12/31 Vue.js
python打开url并按指定块读取网页内容的方法
2015/04/29 Python
python实现实时监控文件的方法
2016/08/26 Python
OpenCV实现人脸识别
2017/04/07 Python
Python实现按学生年龄排序的实际问题详解
2017/08/29 Python
详解opencv Python特征检测及K-最近邻匹配
2019/01/21 Python
python 使用pdfminer3k 读取PDF文档的例子
2019/08/27 Python
执行Python程序时模块报错问题
2020/03/26 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
2020/03/30 Python
pandas to_excel 添加颜色操作
2020/07/14 Python
Python使用windows设置定时执行脚本
2020/11/12 Python
Pycharm配置autopep8实现流程解析
2020/11/28 Python
朗仕(Lab series)英国官网:雅诗兰黛集团男士专属护肤品牌
2017/11/28 全球购物
泰国健康和美容服务预订网站:GoWabi
2019/06/03 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
洗车工岗位职责
2014/03/15 职场文书
小学教师学习党的群众路线教育实践活动心得体会
2014/10/31 职场文书
工作感言一句话
2015/08/01 职场文书
golang通过递归遍历生成树状结构的操作
2021/04/28 Golang
PostgreSQL常用字符串分割函数整理汇总
2022/07/07 PostgreSQL