简述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 相关文章推荐
Javascript中的isNaN函数使用说明
Nov 10 Javascript
javascript加号&quot;+&quot;的二义性说明
Mar 04 Javascript
jQuery实现表单提交时判断的方法
Dec 13 Javascript
深入理解jQuery之事件移除
Jun 02 Javascript
js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】
Aug 02 Javascript
PHP7新特性简述
Jun 11 Javascript
JavaScript实现短信倒计时60s
Oct 09 Javascript
Vue实现美团app的影院推荐选座功能【推荐】
Aug 29 Javascript
vue 弹框产生的滚动穿透问题的解决
Sep 21 Javascript
npm scripts 使用指南详解
Oct 08 Javascript
Javascript中绑定click事件的四种方式介绍
Oct 26 Javascript
微信小程序webview实现长按点击识别二维码功能示例
Jan 24 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 URL验证正则表达式
2011/07/19 PHP
php对象在内存中的存在形式分析
2015/02/03 PHP
CI框架附属类用法分析
2018/12/26 PHP
用AJAX返回HTML片段中的JavaScript脚本
2010/01/04 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
JS实现简单的图书馆享元模式实例
2015/06/30 Javascript
详解Wondows下Node.js使用MongoDB的环境配置
2016/03/01 Javascript
JAVA中截取字符串substring用法详解
2017/04/14 Javascript
webpack使用 babel-loader 转换 ES6代码示例
2017/08/21 Javascript
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
2019/03/13 Javascript
angular6开发steps步骤条组件
2019/07/04 Javascript
vue滑动吸顶及锚点定位的示例代码
2020/05/10 Javascript
js仿京东放大镜效果
2020/08/09 Javascript
VUE : vue-cli中去掉路由中的井号#操作
2020/09/04 Javascript
pyv8学习python和javascript变量进行交互
2013/12/04 Python
python实现将文本转换成语音的方法
2015/05/28 Python
Python中operator模块的操作符使用示例总结
2016/06/28 Python
Python 私有函数的实例详解
2017/09/11 Python
Windows下Python3.6安装第三方模块的方法
2018/11/22 Python
Python设计模式之策略模式实例详解
2019/01/21 Python
django实现支付宝支付实例讲解
2019/10/17 Python
用python打开摄像头并把图像传回qq邮箱(Pyinstaller打包)
2020/05/17 Python
浅谈Selenium 控制浏览器的常用方法
2020/12/04 Python
requests在python中发送请求的实例讲解
2021/02/17 Python
浅谈基于HTML5的在线视频播放方案
2016/02/18 HTML / CSS
美国购买新书和二手书网站:Better World Books
2018/10/31 全球购物
Java里面StringBuilder和StringBuffer有什么区别
2016/06/06 面试题
毕业自我评价范文
2013/11/17 职场文书
高级技校毕业生自荐信
2013/11/18 职场文书
社区爱国卫生月活动总结
2014/06/30 职场文书
公司活动总结范文
2014/07/01 职场文书
保密工作目标责任书
2014/07/28 职场文书
买房协议书范本
2014/10/23 职场文书
投诉信范文
2015/07/02 职场文书
解决redis批量删除key值的问题
2022/03/23 Redis