简述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 相关文章推荐
Mootools 1.2教程 函数
Sep 15 Javascript
网页中CDATA标记的说明
Sep 12 Javascript
js实现简单的星级选择器提交效果适用于评论等
Oct 18 Javascript
深入理解JQuery keyUp和keyDown的区别
Dec 12 Javascript
让浏览器DOM元素最后加载的js方法
Jul 29 Javascript
jquery实现点击其他区域时隐藏下拉div和遮罩层的方法
Dec 23 Javascript
js简单正则验证汉字英文及下划线的方法
Nov 28 Javascript
jquery获取input type=text中的值的各种方式(总结)
Dec 02 Javascript
JavaScript实现的原生态兼容IE6可调可控滚动文字功能详解
Sep 19 Javascript
VSCode配置react开发环境的步骤
Dec 27 Javascript
15 分钟掌握vue-next响应式原理
Oct 13 Javascript
vue中实现拖动调整左右两侧div的宽度的示例代码
Jul 22 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 iconv() : Detected an illegal character in input string
2010/12/05 PHP
简单实现限定phpmyadmin访问ip的方法
2013/03/05 PHP
win7+apache+php+mysql环境配置操作详解
2013/06/10 PHP
php实现的Cookies操作类实例
2014/09/24 PHP
PHP用FTP类上传文件视频等的简单实现方法
2016/09/23 PHP
用JavaScript 处理 URL 的两个函数代码
2007/08/13 Javascript
JavaScript中检测变量是否存在遇到的一些问题
2013/11/11 Javascript
jQuery判断div随滚动条滚动到一定位置后停止
2014/04/02 Javascript
JavaScript实现鼠标点击后层展开效果的方法
2015/05/13 Javascript
JS平滑无缝滚动效果的实现代码
2016/05/06 Javascript
浅析js绑定事件的常用方法
2016/05/15 Javascript
微信小程序中子页面向父页面传值实例详解
2017/03/20 Javascript
基于JS脚本语言的基础语法详解
2017/07/22 Javascript
浅谈ajax请求不同页面的微信JSSDK问题
2018/02/26 Javascript
Puppet的一些技巧
2018/09/17 Javascript
Vue循环组件加validate多表单验证的实例
2018/09/18 Javascript
图文详解vue框架安装步骤
2019/02/12 Javascript
让 babel webpack vue 配置文件支持智能提示的方法
2019/06/22 Javascript
jQuery实现简易聊天框
2020/02/08 jQuery
Jquery高级应用Deferred对象原理及使用实例
2020/05/28 jQuery
[48:32]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs VG
2018/04/01 DOTA
Python类的多重继承问题深入分析
2014/11/09 Python
python3 kmp 字符串匹配的方法
2018/07/07 Python
python 并发编程 非阻塞IO模型原理解析
2019/08/20 Python
pytorch之Resize()函数具体使用详解
2020/02/27 Python
idea2020手动安装python插件的实现方法
2020/07/17 Python
Python发送邮件实现基础解析
2020/08/14 Python
使用CSS3的ruby-position固定注音位置的用法示例
2016/07/05 HTML / CSS
美国东北部户外服装和设备零售商:Eastern Mountain Sports
2016/10/05 全球购物
Airbnb爱彼迎官网:成为爱彼迎房东,赚取收入
2019/03/14 全球购物
size?丹麦官网:英国伦敦的球鞋精品店
2019/04/15 全球购物
物流专业求职计划书
2014/01/10 职场文书
加拿大留学自荐信
2014/01/28 职场文书
《厄运打不垮的信念》教学反思
2014/04/13 职场文书
向女朋友道歉的话
2015/01/20 职场文书
微信小程序APP页面的之间的相互传递参数以及自定义组件
2022/04/19 Javascript