问题描述
本文带领大家通过一个我自己编写的豆瓣电影的小例子认识Angular
。
时代在发展,技术在进步。
为了规避AngularJS
的一些问题,我们打开了Angular
的大门。
思想
随着框架的发展,涌现出了越来越多的开发思想。
从原生JS
操作DOM
,到JQuery
简化DOM
操作,到AngularJS
面向数据开发,再到如今的Angular
的组件化开发。
源于指令
AngularJS
的核心就是指令,ng-app
,ng-controller
,哪怕一个最简单的AngularJS
应用也用到了指令。
而Angular
随着现在组件化开发思想的流行,借鉴了现有框架的优点,可谓优秀。
下图为一个Angular
标准组件的Demo
,这很像AngularJS
的指令,但是AngularJS
的指令嵌套时需要考虑许多复杂的关系,这就使得指令的用武之地大大缩水。
Angular
发现了这个问题,所以组件,是一种易于嵌套的指令。
架构设计
因为项目比较小,所以架构设计的也比较简单。
component
:存放组件。model
:存放数据模型。pipe
:存放管道(过滤器)。service
:存放服务。
实战
环境
UI
框架采用Angular Material
和Bootstrap
,这里用Bootstrap
的原因主要是因为Material
的布局比较难,研究了一下午也没研究明白怎么随心所欲的运用,最后还是引了个Bootstrap
。
如果你在Material
方面造诣比较深的话,用这个就够了,只是笔者初学,还不能灵活的运用Material
。
模型
我们先从模型model
说起,各位开发者对于前台是否应该建实体的观点莫衷一是,这里,我阐述下我自己的观点。
前台有了实体之后,可以对请求时返回的观察者Observable
对象进行类型声明,这样可以让代码更清晰,同时有了实体之后,在TypeScript
中的各种操作都有代码提示,我们再也不需要去控制台console.log
看看这个返回的对象都有些什么属性了,有IDE
为我们进行类型检查,编码时不易出错。
就像Android
一样,对于服务器而言,也是一个前端,也需要建实体,然后转换为相应的数据类型。既然TypeScript
也正在往这方面靠拢,那我们何乐而不为呢?
服务
看下面的代码,我们不需要再去像AngularJS
一样链式调用then
然后再去success
和error
了。
Angular
中结合rxjs
,对于异步有一个新的处理方式----观察者模式。
RxJS
: 用于JavaScript
的响应式拓展库。RxJS
是一个使用观察者模式让异步和基于回调的代码更加容易的响应式编程库。
HttpClient
的请求方法返回的是一个可观察的对象,我们可以订阅这个对象,当发生事件时执行我们的方法,其实也就是回调函数与观察者模式的结合。
组件
这是笔者在项目中编写的几个组件。
在index.html
中使用默认创建的app-root
组件作为应用的起始。
然后app-root
中还有组件,这就是一个组件树,Angular
就从app-root
这个根节点开始渲染该组件树上的各个组件。
组件化开发,我们的项目结构会更清晰,同时每个组件的职责更明确。
生命周期
条条大路通罗马,无论一个框架如何设计,它的本质还是没有变的。
和微信小程序中的组件一样,Angular
的组件也是有生命周期的。
官方文档展示了一个组件从创建到消亡的各种钩子,这些钩子是有时间顺序的。
想要在组件不同的生命周期执行自定义的方法,只需要在组件类中实现相应的接口即可。
还有一个问题就是第一次见Angular
组件的代码时不知道初始化是放在constructor
里还是ngOnInit
里,到了现在也算是有了一些自己的理解。
这个就像在Spring
中使用依赖注入,有时我们会在构造函数中声明要注入的对象,这里的constructor
与ngOnInit
的关系就像Spring
中的构造函数
与@PostConstruct
的关系一样,一个用于构造,一个用于初始化。
所以应该将依赖注入相关的代码声明在constructor
中,初始化方法放在ngOnInit
中。
输入输出
去看文档,使用已有组件会有Input
与Output
代表的输入输出,@Input
标注的属性表示该类型需要外部输入,文档中会给出类型。
Output
标注的属性一般是该组件触发的某些事件,使用EventEmitter
实现自定义事件,调用emit
方法来发布事件。因为我编写的组件功能都比较简单,只有输入,输出的属性我们以后讨论。
管道
管道,也就是我们常说的过滤器,就是一个方法的输入什么,处理完再输出,Angular
中命名为Pipe
。
电影的类型、导演、主演都是拿管道过滤出来的。
这是过滤导演的管道源码:
因为编码的时候只考虑了部分功能,没有对管道有一个整体的认识。
在现在写博客时恍然大悟,这样写,仅仅只能过滤Director
数组,但是我这个方法呢?我这个源码可不仅仅是过滤Director
数组,只要是数组,并且该数组中的对象有name
属性,都可以按规则过滤。
所以接口的价值就体现出来了:
路由
路由用着和之前的ui-router
感觉差不多,不同的路由,就往router-outlet
里嵌套不同的内容。
总结
TypeScript
写着挺爽的,尤其是箭头函数,再也不用去写function
关键字了。
类型检查做得很优秀,不必像我们以往在JavaScript
中写了一个方法,然后去写注释,我的输入应该是个什么类型,对象应该有什么属性,然后可能别人还看不懂。建个接口,清晰简洁,传错了编译器还会提示。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。