国庆时按照官网的tutorial写了遍官方示例,只知其一;不知其二,不明白angular的服务的服务为什么要单独抽离出来、angular应用是如何启用的。近期打算看下angular的文档部分,而后梳理遍以理解angular的架构思想。css
下面是一些须要明确的关键概念:html
*ngFor
、<my-component>
等。@Component
、@Injectable
、@Input
、@Output
添加元数据来指导angular的行为。好比export class MyComponent implements OnInit{}
是一个js的原生类,须要使用@Component(configObj)
附加元数据来修饰这个类,这会将之标记成angular的组件。这是angular的架构图。
angular用组件模块(Module Component)来构成应用程序,并向组件注入服务模块(Module Service)来向模块组件添加应用的逻辑部分,最终使用模块打包器来打包成最终的应用程序。组件模块的命名通常为组件.component.ts
。
通常用模板(Template)来写页面部分,在脚手架中是使用扩展的语法来写html文件,模板名为组件名.component.ts
,模板中能够写angular的指令(directive),而且能够绑定组件模块中的数据(属性绑定、事件绑定等)。
经过向组件注入(inject)服务,可以让组件具备各种功能。
angular应用程序按组件来编写应用程序页面,页面的一小块区域就是一个组件,而且通常会把css与模板抽离成单独的文件。好比有一个分页组件,那么在page-select
文件夹下会有page-elect.component.ts
,page-elect.component.html
,page-elect.component.css
这么三个文件。写组件模块化意味着页面且的解耦,便于维护。
在全部页面组件都编写完成后,angular能够从引导根模块(通常命名为AppModule)来启动应用。前端
angular是模块化的,angular有本身的模块系统NgModules,angular中的模块都是带有@NgModule
装饰器的类,装饰器用来把元数据附加到类上。模块通常都是专一于某个应用领域、某一工做流、或者由一系列功能相近的功能构成的。简单根模块示例:redux
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @NgModule({ imports: [ BrowserModule,FormrModule,HttpModule,ApproutingModule ], providers: [ Logger,SqlServer,CalcServer ], declarations: [ AppComponent ], exports: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
须要注意的是,angular的模块与js的模块系统彻底不一样且无关。不过在angular中它们是互补的。bootstrap
另外,angular提供了一组JS模块,能够把它们看成库模块。前端框架
组件负责控制屏幕一小块区域,也能够叫作视图(view)。
组件主要控制页面UI,建立一个angular组件须要从angular核心模块(@angular/clore
)中引入component
修改器,而后用它来修饰一个JS类,这样auglar就会知道这是一个组件。
简单示例:服务器
@Component({ selector : 'mycomponent', template : '<h2>测试</h2>', directives : [ComponentDetails] }) export class TestComponent{...}
@Component
中的参数是这个组件的配置信息,好比:架构
template
模板,通常是用反引号`括起来的字符串。templateUrl
模板的url,把一个文件看成该组件的模板。templateUrl
与template
并与本质区别,但显然若是模板代码较多应使用templateUrl
。selector
选择器,父组件使用该组件须要使用该选择器的中线命名法(dash-case),好比这个示例就是<my-component></my-component>
。当页面发现一个<my-component>
元素时,就会建立一个该组件TestComponent的实例,而后将其渲染到<my-component>
标记处。directives
组件用到的指令好比@Component
装饰器就是经过给一个js类附加相应的元数据来让angular知道它是一个组件。框架
MVVM框架的一大优势。想象Jquery时代是如何手动push和pull数据的。若是有多种途径能够改变某个值,那么数据的变更就会变得混乱且不方便跟踪。
数据绑定有三个方向: 绑定到 DOM 、绑定自 DOM 以及双向绑定( to the DOM, from the DOM, or in both directions),具体有以下4种形式:dom
{{person.age}}
插值表达式;[name]
属性绑定;[(ngModel)]
双向绑定。Angular 在每一个 JavaScript 事件循环中处理全部的数据绑定,它会从组件树的根部开始,递归处理所有子组件。
数据绑定也在父子组件的通信间起到做用。但若是同级组件、或者多个组件间须要共享数据的话,只使用数据绑定会把事情弄的复杂。这时候就须要使用状态管理如ngrx和redux,在angular的官方示例中有专门的服务。
数据绑定被人称做单向数据绑定(one-way data binding),由于只能从组件的数据流动到目标的元素,而不能从目标元素流动到组件的数据中。一样的,也不能用数据绑定来调用目标元素上的方法。
@Component
装饰器实际就是一个
@Directive
装饰器。
*ngIf
、
*ngFor
。
ngModel
实现了双向绑定,
Ngclass
用于添加或者移除CSS类,
NgStyle
用于添加或移除一组CSS样式。
按照个人理解,服务是指将组件中的一些功能单独抽离出来,以保持组件的精简。
好比一个简单的购物车组件Cart
,固然能够在其中定义大量的方法好比获取商品的详细信息的方法getDetail
、判断仓库是否还有剩余你选中的商品isRest
、根据你购物车中的商品给出推荐的搭配match
,甚至还有对比购物车中商品在不一样店铺中的价格等等各种功能。若是你想,你能够为一个购物车写上十几种方法,但如今这个组件就会显得很复杂。若是把这个方法抽离成独立的服务,好比商品信息获取服务、推荐搭配服务、价格比对服务等,单独写到一个文件中,再导入到组件,这就会显得比较简洁。
angular推荐的做法:组件只提供用户体验,它介于视图与应用逻辑之间,并把诸如写日志之类的任务委托给服务;服务自己不从服务器得到数据、不进行验证输入。
虽然这些要求不是强制性的,但显然将任务委托给服务能让代码更容易看懂些。
能够经过查看构造函数的参数类型得知须要哪些服务,好比如下示例类须要一个ServiceA服务:constructor(private service:ServiceA){}
当 Angular 建立组件时,会首先为组件所需的服务请求一个注入器 (injector)。 注入器维护了一个服务实例的容器,存放着之前建立的实例。 若是所请求的服务实例不在容器中,注入器就会建立一个服务实例,而且添加到容器中,而后把这个服务返回给 Angular。 当全部请求的服务都被解析完并返回时,Angular 会以这些服务为参数去调用组件的构造函数。 这就是依赖注入 。