Angular 词汇表
1. 概要
大多数 Angular 短语都是日常用语或计算机术语,但是在 Angular 体系中,它们有特别的含义。
1. 概要
预编译 (ahead-of-time, AOT)
即时编译 (just-in-time, JIT)
Angular元素(element, Angular Element)
注解(Annotation): 注解也叫装饰器;
装饰器(decorator | decoration): 注解也叫装饰器;
应用外壳(app-shell)
架构(Architect)
指令 directives
属性型指令(attribute directives)
绑定 (binding)
启动/引导 (bootstrap)
构建器(Builder)
大小写类型(case types)
小驼峰形式(camelCase):小驼峰(也叫标准驼峰)形式的第一个字母要使用小写形式。
大驼峰形式(UpperCamelCase)或叫帕斯卡形式(PascalCase)
中线形式(dash-case)或叫烤串形式(kebab-case)
下划线形式(underscore_case)或叫蛇形形式(snake_case)
大写下划线形式(UPPER_UNDERSCORE_CASE)或叫大写蛇形形式(UPPER_SNAKE_CASE)
变更检测(change detection)
类装饰器(class decorator)
类字段装饰器(class field decorator)
集合(collection)
命令行工具,命令行客户端(CLI, Angular CLI)
组件 (component)
配置(configuration)
内容投影 (content projection)
自定义元素(Custom element):也叫 Web Component
数据绑定 (data binding)
可声明对象(declarable)
装饰器(decorator | decoration)
依赖注入(dependency injection)
DI 令牌(Token)
差异化加载 (differential loading)
指令 (directive)
领域特定语言(domain-specific language, DSL)
动态组件加载(dynamic component loading)
急性加载(Eager Loading)
惰性加载(Lazy loading)
元素(Element, Angular Element)
入口点(Entry Point)
表单控件(form control)
表单模型(form model)
表单验证(form validation)
不可变性(immutability)
可注入对象(injectable)
注入器 (injector)
输入属性 (input)
输出属性 (output)
插值 (interpolation)
常春藤引擎(Ivy)
惰性加载(Lazy loading)
库(Library)
生命周期钩子(Lifecycle hook)
模块 (module)
ngcc (Angular 兼容性编译器)
npm 包 (npm package)
ngc (ngc 是一个 TypeScript 到 JavaScript 的转译器)
可观察对象(Observable)
观察者(Observer)
管道(pipe)
平台(platform)
腻子脚本(polyfill)
项目(project)
提供者 (provider)
响应式表单 (reactive forms)
解析器(resolver)
路由守卫 (route guard)
路由器 (router)
路由出口(router outlet)
路由组件 (routing component)
规则(rule)
原理图(schematic)
Schematics CLI (Schematics 自带了一个命令行工具)
范围化包 (scoped package)
服务端渲染 (server-side rendering)
服务 (service)
结构型指令(Structural directives)
订阅者(Subscriber)
目标 (target)
模板 (template)
模板驱动表单(template-driven forms)
模板表达式(template expression)
模板引用变量 (template reference variable)
令牌(Token)
转译(transpile)
目录树(tree)
TypeScript 配置文件
单向数据流 (unidirectional data flow)
视图 (view)
视图引擎(View Engine)
视图树(View hierarchy)
Web 组件 (web component)
工作空间(Workspace)
工作空间配置(Workspace configuration)
区域 (zone)
—————- END —————-
======================
javascript中常见的非人类(java/c#)知识

1. 概要
众所周期,javascript是一个很老的语言,起起伏伏,逐渐成为流行语言(主流语言),说白了,也是因为早期各个浏览器(ie/firefox/sarfari/chrome)互不妥协,谁也说服不了对方接收自己的标准,不过却都同时支持javascript。对于广大程序员来说,随着web流行度越来越高,那么为了同时支持大多数浏览器,那么使用标准的javascript成为趋势。而第三方(coffeescript, typescript, dart等)也都是选择将代码编译为JavaScript,然后在浏览器端执行。
作为从C#、java等语言转到javascript的同学来说,会发现不少C#、java的“我觉得应该是这样”的东西,JavaScript中却是不一样的。下面总结一下
2. this
对C#、Java等语言,this就是当前对象,但是javascript不是,简单来说:
- 全局this 是window;
- 函数this 是调用者;
- 构造函数的this 是new 之后的新对象,
- call 和 apply bind的this第一个参数
3. 原型链, prototype
- 函数对象都包含prototype属性(函数的原型对象),其作用就是让该函数所实例化的对象们都可以找到公用的属性和方法;
- constructor属性的含义就是指向该对象的构造函数
- ①__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性。
- JavaScript 的每个对象都继承另一个父级对象,父级对象称为原型 (prototype) 对象。
- 每一个实例对象都有一个私有属性__proto__指向其构造函数的原型对象prototype;该原型对象也会作为实例对象有一个私有属性__proto__,层层向上直到一个对象的原型对象值为null。
- 当访问一个对象的属性或方法时,js引擎会先查找该对象本身是否包含,如果没有,会去该对象的__proto__属性所指向的原型对象上找,如果没有,会继续向上一层找,直到某个对象的__proto__值为null,这就是原型链。
- 每个构造函数都有一个prototype属性,指向另外一个对象,说明整个对象所有的属性和方法都会被构造函数所拥有。
4. new操作符都做了什么
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一。
new Object()举例:
- 创建一个新对象
- 把新对象的原型指向构造函数的prototype
- 把构造函数里的this指向新对象
- 返回这个新对象
5. === VS ==
1 | 100 == '100' // true |
很有意思吧, 看看这两个,是等效的:
1 | obj == null |
6. 闭包
在JavaScript中的一大特点就是闭包,很多高级应用(早期的jquery,现在的angular、vue)都要依靠闭包来实现。由于闭包会使得函数中的变量都被保存在内存中,会消耗很大的内存,导致页面的性能问题,甚至导致内存泄漏。建议不要或者少用闭包。
1 | function outerMethod() { |
7. 总结
- Javascipt 中有些内容和其他编程语言不一致,需要牢记
- JavaScript中拿不准的东西,可以简单测试一下,免得代码写好后出错。
- 简单测试,可以打开浏览器,直接F12(进入Dev Tools),再选择Console(控制台), 直接输入要测试的内容,查看返回结果
—————- END —————-
======================
Angular入门到精通系列教程(15)- 目录结构(工程结构)推荐
环境:
- Angular CLI: 11.0.6
- Angular: 11.0.7
- Node: 12.18.3
- npm : 6.14.6
- IDE: Visual Studio Code
1. 概要
实际的Angular项目,肯定不是一个简单的Hello World程序,会包含很多的功能,很多的文件。那么如何更好的组织这些文件呢?官方给了一个原则,可以供参考:
https://angular.io/guide/styleguide#application-structure-and-ngmodules。
下面,我们来通过一个例子具体解释一下。
2. 目录结构(工程结构)推荐
2.1. 总的原则
- 基于Angular CLI创建模块(module),组件(component)等等的内容;
- 源代码都放到
src文件夹下; - 应用的根目录创建一个 NgModule, 并命名为app.module.ts(例如 /src/app,这个Angular CLI 会自动帮我们做)
- 组件具有多个伴生文件 (.ts、.html、.css 和 .spec),建议为它创建一个文件夹;(Angular CLI 会自动帮我们做)
- 为每一组功能(特性区)创建一个模块(
NgModule);(这个也方便我们应用惰性加载/延迟加载,预加载) - 在 src/app/shared 目录中创建名叫 SharedModule 的共享模块,方便其他功能调用;
2.2. 实例
1 | src/ 目录下: |
说明:
- 根目录下的
NgModule默认是app.module.ts, 不要改名,方便阅读 - app 下,每个目录,同时也都是一个模块-
NgModule - 一个项目,一般包含多个功能(feature)模块
- 推荐使用共享模块-SharedModule,将通用的、功能的功能(service/component/pipe等)放到改模块中。 (下文详细介绍)
- 推荐使用核心模块-CoreModule,可以将项目的一些全局的设置、UI等放到该模块。如header、footer组件,安全组件(服务),上下文存储服务等。
2.3. 共享模块-SharedModule
上文提到,推荐使用共享模块-SharedModule,将通用的、功能的功能(service/component/pipe等)放到改模块中。具体存放内容包括:
- 共享模块中声明那些可能被特性模块引用的可复用组件(Component)、指令(Directive)和管道(Pipe)。
- 如果放置服务(Service),由于服务的单例特性,共享模块中只建议放置无状态的服务(Service),对于有状态、或者和业务紧密相关的服务,建议放到CoreModule中。
- SharedModule 中声明(declarations)和导出(exports)所有组件、指令和管道,方便其他模块调用
- 共享模块(SharedModule)在项目中处于底层,从逻辑上,只能由其他业务逻辑模块调用,不能调用其他模块;
- 共享模块(SharedModule)不建议使用延迟加载(惰性加载),因为这样会破坏服务的单例特性;
3. 高级应用 - angular库、工作空间(workspace )
想一想你是如何安装angular相关的类库的?我们使用的是npm install xxx。那么这些第三方angular库是如何开发的呢?我们是否可以把通用的内容写成Angular类库,然后方便在多个angular项目间共享了?又或者直接发布到官方npm站点?
Angular 从6.0开始,引入了工作区的概念。使用Angular CLI,默认创建的就是一个工作空间(workspace)。一个工作空间(workspace)可以有一个主项目,同时可以有多个子项目。当然这些子项目可以是angular的application, 也可以是Library。Angular的子项目,都在app下的projects 之下,和src目录平级。
这样,一般来说,我们的项目中,除了主程序,还可以包含多个子类库。这样在开发时方便主程序、类库同时开发调试;也可以项目结束后,单独发布类库,实现项目之间的代码共享。
创建子项目也很简单,子项目有2种类型,application(可以启动的)和Library(Angular类库),默认都在projects文件夹下:
- 创建子Applicaton
1 | ng generate application <name> [options] |
- 创建子类库(Angular Library)
1 | ng generate library <name> [options] |
3.1. 目录结构示意
1 | +---projects |
4. 总结
- Angular CLI默认创建的Angular项目,实际是一个工作空间(workspace ),在其内部还可以创建多个子项目
- 子项目可以是Application,也可以是类库(Library);
- 对于主项目(一般来说是一个Application),以功能模块的方式进行组织;
- 公共内容,建议放到共享模块-SharedModule中。
- 对于功能模块,可以通过惰性加载(延迟)加载,提高首页加载速度;同时通过预加载技术,可以在空闲时间加载这部分模块,使用户体验更好。
—————- END —————-
======================
CSS3 Flex Box 弹性盒子、弹性布局
- 1. 概要
- 2. justify-content 属性
- 3. align-items 属性
- 4. flex-wrap 属性
- 5. align-content 属性
- 6. 居中
- 7. align-self
- 8. 总结
1. 概要
Flexible Box翻译过来就是弹性盒子、弹性布局,是css3中新增的一种布局方式,是当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。引入弹性布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。
弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成。
- 弹性容器通过设置 display 属性的值为 flex 或 inline-flex将其定义为弹性容器。
- 弹性容器内包含了一个或多个弹性子元素。
| 属性 | 描述 |
|---|---|
| display | 指定 HTML 元素盒子类型。 |
| flex-direction | 指定了弹性容器中子元素的排列方式 |
| justify-content | 设置弹性盒子元素在主轴(横轴)方向上的对齐方式。 |
| align-items | 设置弹性盒子元素在侧轴(纵轴)方向上的对齐方式。 |
| flex-wrap | 设置弹性盒子的子元素超出父容器时是否换行。 |
| align-content | 修改 flex-wrap 属性的行为,类似align-items, 但不是设置子元素对齐,而是设置行对齐 |
| flex-flow | flex-direction 和 flex-wrap 的简写 |
| order | 设置弹性盒子的子元素排列顺序。 |
| align-self | 在弹性子元素上使用。覆盖容器的 align-items 属性。 |
| flex | 设置弹性盒子的子元素如何分配空间。 |
2. justify-content 属性
内容对齐(justify-content)属性应用在弹性容器上,把弹性项沿着弹性容器的横轴(主轴线,main axis)对齐。
·justify-content 语法:
1 | justify-content: flex-start | flex-end | center | space-between | space-around |
可选项:
- flex-start:弹性项目向行头紧挨着填充。这个是默认值。第一个弹性项的main-start外边距边线被放置在该行的main-start边线,而后续弹性项依次平齐摆放。
- flex-end:弹性项目向行尾紧挨着填充。第一个弹性项的main-end外边距边线被放置在该行的main-end边线,而后续弹性项依次平齐摆放。
- center:弹性项目居中紧挨着填充。(如果剩余的自由空间是负的,则弹性项目将在两个方向上同时溢出)。
- space-between:弹性项目平均分布在该行上。如果剩余空间为负或者只有一个弹性项,则该值等同于flex-start。否则,第1个弹性项的外边距和行的main-start边线对齐,而最后1个弹性项的外边距和行的main-end边线对齐,然后剩余的弹性项分布在该行上,相邻项目的间隔相等。
- space-around:弹性项目平均分布在该行上,两边留有一半的间隔空间。如果剩余空间为负或者只有一个弹性项,则该值等同于center。否则,弹性项目沿该行分布,且彼此间隔相等(比如是20px),同时首尾两边和弹性容器之间留有一半的间隔(1/2*20px=10px)。
3. align-items 属性
align-items 设置或检索弹性盒子元素在侧轴(纵轴)方向上的对齐方式。
align-items语法
1 | align-items: flex-start | flex-end | center | baseline | stretch |
可选项:
- flex-start:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
- flex-end:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
- center:弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
- baseline:如弹性盒子元素的行内轴与侧轴为同一条,则该值与’flex-start’等效。其它情况下,该值将参与基线对齐。
- stretch:如果指定侧轴大小的属性值为’auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照’min/max-width/height’属性的限制。
4. flex-wrap 属性
flex-wrap 属性用于指定弹性盒子的子元素换行方式。
语法
1 | flex-wrap: nowrap|wrap|wrap-reverse|initial|inherit; |
可选项:
- nowrap - 默认,弹性容器为单行。该情况下弹性子项可能会溢出容器。
- wrap - 弹性容器为多行。该情况下弹性子项溢出的部分会被放置到新行,子项内部会发生断行
- wrap-reverse -反转 wrap 排列。
5. align-content 属性
align-content 属性用于修改 flex-wrap 属性的行为。类似于 align-items, 但它不是设置弹性子元素的对齐,而是设置各个行的对齐。
语法
1 | align-content: flex-start | flex-end | center | space-between | space-around | stretch |
各个值解析:
- stretch - 默认。各行将会伸展以占用剩余的空间。
- flex-start - 各行向弹性盒容器的起始位置堆叠。
- flex-end - 各行向弹性盒容器的结束位置堆叠。
- center -各行向弹性盒容器的中间位置堆叠。
- space-between -各行在弹性盒容器中平均分布。
- space-around - 各行在弹性盒容器中平均分布,两端保留子元素与子元素之间间距大小的一半。
6. 居中
使用弹性盒子,居中变的很简单,只想要设置 margin: auto; 可以使得弹性子元素在两上轴方向上完全居中:
如
1 | .flex-item { |
7. align-self
align-self 属性用于设置弹性元素自身在侧轴(纵轴)方向上的对齐方式。
选项:
- auto:如果’align-self’的值为’auto’,则其计算值为元素的父元素的’align-items’值,如果其没有父元素,则计算值为’stretch’。
- flex-start:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴起始边界。
- flex-end:弹性盒子元素的侧轴(纵轴)起始位置的边界紧靠住该行的侧轴结束边界。
- center:弹性盒子元素在该行的侧轴(纵轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
- baseline:如弹性盒子元素的行内轴与侧轴为同一条,则该值与’flex-start’等效。其它情况下,该值将参与基线对齐。
- stretch:如果指定侧轴大小的属性值为’auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照’min/max-width/height’属性的限制。
8. 总结
1.
—————- END —————-
======================
Angular入门到精通系列教程(14)- Angular 编译打包 & Docker发布
环境:
- Angular CLI: 11.0.6
- Angular: 11.0.7
- Node: 12.18.3
- npm : 6.14.6
- IDE: Visual Studio Code
1. 概要
当我们完成angular的开发后,如何部署到服务器呢?
2. 编译打包
2.1. 基本打包命令
基于Angular CLI生成的Angular项目,默认会有2个环境配置文件
1 | └──myProject/src/environments/ |
- environment.ts: 针对开发环境使用的环境文件
- environment.prod.ts: 生产环境编译时,将替换原有的environment.ts,然后再打包。 (根目录下的angular.json定义了这个默认行为,有需要,可以进行修改)
AngularCLI刚刚生成2个文件后,如果打开比较2个文件的区别,可以看到开发环境使用的environment.ts文件中,有这么一句production: false。因为,针对生产环境,angular在编译时需要核心考虑效率等问题,而开发环境,要考虑方便开发者进行调试,侧重点不同。
那么针对生产环境如何编译呢?Angular CLI同样提供了命令,
1 | ng build --prod |
其中,参数--prod 即告诉编译环境,编译为生产环境包。同样,angular.json中定义了默认的编译参数,如果需要,可以进行修改。主要配置参数如下
1 | "configurations": { |
Angular默认打包到根目录下的dist目录下,生成的文件为纯静态文件(html, css, js),以及图片文件。
2.2. 打包部署到二级目录
有不少情况,我们的angular web站点不能直接部署到网站的根目录下,需要部署到二级目录下。 比如,不能部署到 http://abc.com下,要求部署到 http://abc.com/demo 这个二级目录下。针对这种情况,就需要修改一下我们的编译参数,修改为:
1 | ng build --prod --deploy-url /demo/ --base-href /demo/ |
增加 --deploy-url 和 --base-href。
使用场景:比如我们有多个站点,希望使用同一个反向代理,
http://site1,http://site2, 分别映射到http://abc.com/site1,http://abc.com/site2/。 那么为了方便配置,需要把site1, site2都部署到二级目录,如http://site1/site1,http://site2/site2。 然后http://site1/site1代理到http://abc.com/site1,http://site2/site2代理到http://abc.com/site2/, 免得css、js因为目录级别问题找不到。
3. Angular站点的发布
Angular站点编译打包后,可以方便的发布到已有web服务器,或者打成docker image, 然后发布。
3.1. web服务器发布
因为我们打包后,生成的文件为纯静态文件(html, css, js, 图片等), 所以打包后的问题,可以直接copy到iis, nginx , apache tomcat等web服务器,或者node.js, java等可以显示静态文件的程序的目录下即可。
3.2. 使用docker发布
如果部署到docker,我们可以基于一个基础的nginx docker, 然后把编译好的angular项目,copy到docker 内的nginx目录下即可。
基本步骤:
- 准备Dockerfile 文件, docker可以基于
nginx:alpine, 将编译好的angular 站点文件复制到 docker 的nginx默认目录/usr/share/nginx/html
1 | FROM nginx:alpine |
说明: 1) 假设angular打包后的文件,与Dockerfile文件在同一个目录
2) COPY . /usr/share/nginx/html, 两个参数.代表当前路径,/usr/share/nginx/html是docker中的目标目录
- 编译docker。 在Dockerfile目录下,执行
1 | docker build -t your-docker-name . |
三条命令分别为:
- 生成docker image, 名字(name)为your-docker-name
- 导出docker image为本地文件, 文件名为 your-docker-name.tar
- 压缩docker image
可以看到,因为angular编译后为纯静态文件,所以使用docker发布非常简单。部署时,只需要复制docker文件到目标机器,解压缩,然后执行 docker load < your-docker-name.tar 即可加载docker image到目标机器。
4. 总结
- 为生产环境编译,一定要加参数
--prod - 如果要部署到二级目录,编译时加参数。如部署到/demo二级目录下,加参数:
--deploy-url /demo/ --base-href /demo/ - 使用docker发布,可以选择基本的nginx docker, 然后将编译好的angular文件copy到nginx目录下即可。
—————- END —————-
======================
Angular入门到精通系列教程(13)- 路由守卫(Route Guards)
环境:
- Angular CLI: 11.0.6
- Angular: 11.0.7
- Node: 12.18.3
- npm : 6.14.6
- IDE: Visual Studio Code
1. 摘要
在我们的实际的业务开发过程中,我们经常会遇到如下需求:
- 需要限制某些 URL 的可访问性,例如,对于系统管理界面,只有那些拥有管理员权限的用户才能打开。
- 当用户处于编辑界面时,在没有保存就离开时,需要提示用户是否放弃修改。
针对以上场景,Angualr使用路由守卫(Route Guards)来实现。
2. 路由守卫(Route Guards)
2.1. 创建路由守卫
Angular CLI提供了命令行工具,可以快速创建路由守卫框架文件:ng generate guard auth。 执行后,Angular CLI会问我们需要实现哪些接口,我们直接勾选即可:
1 | ? Which interfaces would you like to implement? (Press <space> to select, <a> to toggle all, <i> to invert selection) |
说明:
- CanActivate: 控制路由是否可以激活
- CanActivateChild: 控制子路由是否可以激活
- CanDeactivate: 控制路由是否可以退出
- CanLoad: 控制模块(module)是否可以被加载
比较经常使用的是1、3,分别控制进入和退出。 按照上面配置,AngularCLI自动生成如下代码,return true; 替换为我们实际的代码即可。return false; 表示不允许跳转,或者取消离开当前页面。
1 | // auth.guard.ts |
在canActivate方法中,我们还可以使用跳转。如页面判断是否已经登录,如果没有登录,跳转到Login页面:
1 | this.router.navigate(['/login']); |
2.2. 控制路由是否可以激活
控制路由是否可以激活,需要定义在定义路由的地方,增加canActivate属性。如果需要,还可以增加data属性, 比如告诉我们的AuthGuard进入当前路由需要验证哪些权限。data属性是可选的。
1 | const routes: Routes = [ |
2.3. 控制路由是否退出(离开)
和控制路由是否可以激活类似,在路由定义出增加 canDeactivate,并制定相应的Guard守卫即可。这里不再举例
3. 总结
- 通过路由守卫(Route Guards)实现控制URL的进入和离开;
- Angular CLI可以辅助我们创建guard文件;
—————- END —————-
======================
Angular入门到精通系列教程(12)- 路由(Routing)
环境:
- Angular CLI: 11.0.6
- Angular: 11.0.7
- Node: 12.18.3
- npm : 6.14.6
- IDE: Visual Studio Code
1. 摘要
简单来说地址栏中,不同的地址(URL)对应不同的页面,这就是路由。同时,点击浏览器的前进和后退按钮,浏览器就会在你的浏览历史中向前或向后导航,这也是基于路由。
在 Angular 里面,Router 是一个独立的模块,定义在 @angular/router 模块中,
- Router 可以配合 NgModule 进行模块的延迟加载(懒加载)、预加载操作(参考《Angular入门到精通系列教程(11)- 模块(NgModule),延迟加载模块》);
- Router 会管理组件的生命周期,它会负责创建、销毁组件。
对于一个新的基于AngularCLI的项目,初始化时可以通过选项,将AppRoutingModule默认加入到app.component.ts中。
2. 路由(Router)基本用法
2.1. 准备
我们首先创建2个页面,用于说明路由的使用:
1 | ng g c page1 |
使用上面AnuglarCLI命令,创建Page1Component, Page2Component 2个组件。
2.2. 注册路由
1 | //src\app\app-routing.module.ts |
可以看到,简单的路由注册,只需要path和component2个属性,分别定义路由的相对路径,以及这个路由的响应组件。
2.3. html中的用法
1 | <a routerLink="page1">Page1</a> | |
在html模板中,直接使用routerLink属性,标识为angular的路由。执行代码,可以看到 Page1和Page2 两个超链接,点击可以看到地址栏地址改为http://localhost:4200/page2或http://localhost:4200/page1, 页面内容在page1和page2中切换
2.4. ts 代码中的用法
有时候,需要根据ts中的业务逻辑,进行跳转。ts中,需要注入Router实例,如
1 | constructor(private router: Router) {} |
跳转代码:
1 | // 跳转到 /page1 |
3. 接收参数
3.1. 路径中的参数
一般来说,我们把参数作为url中的一段,如/users/1, 代表查询id是1的用户,路由定义为”/users/id” 这种风格。
针对我们的简单页面,比如我们的page1页面可以传id参数,那么我们需要修改我们的routing为:
1 | const routes: Routes = [ |
ts代码读取参数时, 首先需要注入ActivatedRoute,代码如下:
1 | constructor(private activatedRoute: ActivatedRoute) {} |
3.2. 参数(QueryParameter)中的参数
参数还有另外一种写法,如http://localhost:4200/?name=cat, 即URL地址后,加一个问号’?’, 之后再加参数名和参数值(’name=cat’)。这种称为查询参数(QueryParameter)。
取这查询参数时,和之前的路由参数类似,只是paramMap改为queryParamMap,代码如下:
1 | this.activatedRoute.queryParamMap.subscribe((params) => { |
4. URL路径显示格式
不同于传统的纯静态(html)站点,angular中的url不是对应一个真实的文件(页面),因为anuglar接管的路由(Routing)处理,来决定显示那个Component给终端用户。为了针对不同的场景,angular的URL路径显示格式有2中:
默认是第一种,不加#的。如果需要,可以在app-routing.ts中,加入useHash: true, 如:
1 | // app-routing.ts |
5. 部署中遇到的问题
同样,因为anuglar接管的路由(Routing)处理,所以部署时,部署到iis, nginx等等的服务器,都会有不同的技巧(要求),详细参考:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
6. 总结
- angular默认不支持可选路由(e.g. /user/:id?),但是我们可以定义2个路由,指向同一个Component来实现这个,达到代码复用;(或者使用redirectTo)
- 可以使用useHash参数,实现augular路径前加一个#;
- 读取参数时,都需要subscribe订阅一下,不能直接读取。
- 打包后部署问题,查看官方wifi (https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode)
—————- END —————-
======================
Angular入门到精通系列教程(10)- 指令(Directive)
环境:
- Angular CLI: 11.0.6
- Angular: 11.0.7
- Node: 12.18.3
- npm : 6.14.6
- IDE: Visual Studio Code
1. 摘要
指令(Directive)在Angular 1.0时代(当时叫AngularJS)是很流行的,现在用到的偏少。可以简单理解为,指令(Directive)用于扩展已有Element(DOM)。
2. 组件与指令之间的关系
如果去看Angular源码,可以看到下面定义
1 | /** |
是的,Component派生于Directive,也就是说,Component属于Directive。
2.1. 指令的种类
- Component 是 Directive 的子接口,是一种特殊的指令,Component 可以带有 HTML 模板,Directive 不能有模板。
- 属性型指令:用来修改 DOM 元素的外观和行为,但是不会改变DOM 结构,Angular 内置指令里面典型的属性型指令有 ngClass、ngStyle,如果打算封装自己的组件库,属性型指令是必备的内容。
- 结构型指令:可以修改 DOM 结构,内置的常用结构型指令有
*ngFor、*ngIf和*ngSwitch。由于结构型指令会修改 DOM 结构,因而同一个 HTML 标签上面不能同时使用多个结构型指令。如果要在同一个 HTML 元素上面使用多个结构性指令,可以考虑加一层空的元素来嵌套,比如在外面套一层空的(div) 。
3. Angular 中指令的用途
Angualr中用指令来增强DOM的功能,包括 HTML 原生DOM和我们自己自定义的组件(Component)。举例来说,可以扩展一个Button,实现避免点击后,服务器端未响应前的二次点击;高亮某些收入内容等等。
4. 指令举例
4.1. 指令功能
实现一个指令,鼠标移动到上面时, 背景显示为黄色,鼠标移开,恢复正常。
4.2. Anuglar CLI生成基本文件
1 | ng generate directive MyHighlight |
Anuglar CLI自动生成html、css、ut等文件。
4.3. Directive指令核心代码
1 | import { Directive, ElementRef } from '@angular/core'; |
4.4. 使用该指令
1 | <p my-highlight>Highlight me!</p> |
my-highlight即我们的元素扩展属性(指令、directive)。
5. 总结
- 指令(Directive)用于扩展DOM 元素或组件的功能。
- Angular中的
*ngFor、*ngIf和*ngSwitch都是Angular内置的指令。
—————- END —————-
======================
Angular入门到精通系列教程(7)- 组件(@Component)基本知识
环境:
- Angular CLI: 11.0.6
- Angular: 11.0.7
- Node: 12.18.3
- npm : 6.14.6
- IDE: Visual Studio Code
1. 概述
组件是 Angular 应用的主要构造块。每个组件包括如下部分:
- 一个 HTML 模板,用于声明页面要渲染的内容
- 一个用于定义行为的 Typescript 类
- 一个 CSS 选择器,用于定义组件在模板中的使用方式
- (可选)要应用在模板上的 CSS 样式
Component可以是一个页面,也可以是一个组件(控件)。总是,是一个页面元素。
任何一个Component都是NgModule的一部分,这样它就可以被其他应用和其他Component所调用。为了定义Component是NgModule的一个成员之一,开发者应该在NgModule的declarations属性中,将自己开发的Component列出。
另外,通过Component修饰符(也就是@Component)开发者可以配置元数据,这样通过各式各样的Life-Cycle hooks,Components就可以控制他们的运行环境。
2. 创建Component
基于AngularCLI,可以很方便的创建Component。在要创建Component的目录下,执行如下命令
1 | ng generate component <component-name> |
e.g. ng generate component MyComponent
AngularCLI会自动生成一个文件夹和4个文件:
- 一个以该组件命名的文件夹(e.g my-component)
- 一个组件文件 < component-name >.component.ts(e.g my-component.component.ts)
- 一个模板文件 < component-name >.component.html(e.g my-component.component.html)
- 一个 CSS 文件, < component-name >.component.css(e.g my-component.component.css)
- 测试文件 < component-name >.component.spec.ts(e.g my-component.component.spec.ts)
对于Component,所有文件名都会自动增加Component后缀,所以不建议< component-name > 中带有‘component’这个单词。
1 | @Component({ |
以上是核心的ts文件,指定了selector(CSS 选择器),template(html)文件,css文件。html/css文件如果需要可以多个component公用。尤其是css,可以看到参数是Array,所以可以制定多个css。
2.1. 组件模板
组件模板,即HTML部分,可以是一个html文件,也可以是一段html描述,是等价的。Angular 组件需要一个用 template 或 templateUrl 定义的模板。但你不能在组件中同时拥有这两个语句。
- html 文件方式
1 | @Component({ |
- html代码方式
1 | @Component({ |
可以看到,增加了一个encapsulation属性 (视图封装模式)。通过在组件的元数据上设置视图封装模式,你可以分别控制每个组件的封装模式。 可选的封装模式一共有如下几种:
- Emulated 模式(默认值)通过预处理(并改名)CSS 代码来模拟 Shadow DOM 的行为,以达到把 CSS 样式局限在组件视图中的目的。 更多信息,见附录 1。(说明:只进不出,全局样式能进来,组件样式出不去)
- ShadowDom 模式使用浏览器原生的 Shadow DOM 实现来为组件的宿主元素附加一个 Shadow DOM。组件的视图被附加到这个 Shadow DOM 中,组件的样式也被包含在这个 Shadow DOM 中。(说明:不进不出,没有样式能进来,组件样式出不去。)
- None 意味着 Angular 不使用视图封装。 Angular 会把 CSS 添加到全局样式中。而不会应用上前面讨论过的那些作用域规则、隔离和保护等。 从本质上来说,这跟把组件的样式直接放进 HTML 是一样的。
3.1. 特殊的选择器 :host
使用 :host 伪类选择器,用来选择组件宿主元素中的元素(相对于组件模板内部的元素)。 :host 选择是是把宿主元素作为目标的唯一方式。除此之外,你将没办法指定它, 因为宿主不是组件自身模板的一部分,而是父组件模板的一部分。
e.g.
1 | :host { |
3.2. inline-styles
默认AngularCLI生成的component,css在一个单独文件中。当然,同html模板类似,如果需要,你也可以制定css样式写在ts中, 不单独放到一个文件中。命令:ng generate component MyComponent --inline-style。
生成component如下
1 | @Component({ |
4. 总结
- Angular CLI辅助创建一个component所需的多个文件
- 建议html/css/ts分开
- 在期望目录下执行Angular CLI命令,可以生成到制定目录
ng generate component XXX可以简写为ng g c
—————- END —————-
======================