一、基础
1.模块:
NgModule是一个装饰器函数,它接收一个用来描述模块属性的元数据对象。其中最重要的属性是:
- declarations:声明本模块中拥有的视图类。组件、指令、管道](https://angular.cn/docs/ts/latest/guide/pipes.html)。
- exports:declarations 的子集,可用于其它模块的组件模板。
P.s:根模块不需要导出任何东西 - imports:本模块声明的组件模板需要的类所在的其它模块。
- providers: 服务的创建者,并加入到全局服务列表中,可用于应用任何部分。
- bootstrap:指定应用的主视图(称为根组件),它是所有其它视图的宿主。只有根模块才能设置bootstrap属性。
2. 组件:
- 组件元数据
- 组件的输入输出属性
- 父组件通过属性绑定的形式向子组件传递数据
@Input()
- 子组件通过事件绑定的形式向父组件传递数据
@Output() something =new EventEmitter();
doSomething(){
this.something.emit() //方法emit(value?: T)用来发射值,
}
- 拦截输入属性
- 通过setter拦截输入属性,再通过getter返回要设置的属性。
- 通过ngOnChanges监听数据变化,该方法接受一个SimpleChanges对象。
- 其他组件交互方式
- 父组件通过局部变量获取子组件的引用。
父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法。 - 使用@ViewChild实现数据交互。
这个本地变量方法是个简单便利的方法。但是它也有局限性,因为父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的代码对子组件没有访问权。
如果父组件的类需要读取子组件的属性值或调用子组件的方法,就不能使用本地变量方法。
当父组件类需要这种访问时,可以把子组件作为ViewChild,注入到父组件里面。
首先,你要使用@ViewChild
装饰器导入这个引用,并挂上AfterViewInit
生命周期钩子。接着,通过@ViewChild
属性装饰器,将子组件xComponent
注入到私有属性yComponent
里面。 - 父组件和子组件通过服务来通讯
- 内容嵌入
- 组件的生命周期
- ngOnChanges
一旦检测到该组件(或指令)的输入属性发生了变化,Angular就会调用它的ngOnChanges()方法。 - ngOninit
使用ngOnInit
有两个原因:
在构造函数之后马上执行复杂的初始化逻辑。
在Angular设置完输入属性之后,对该组件进行准备。
我们访问这些属性的第一次机会,实际上是ngOnChanges()方法,Angular会在ngOnInit()之前调用它。 但是在那之后,Angular还会调用ngOnChanges()很多次。而ngOnInit()只会被调用一次。 - ngDoCheck
使用DoCheck
钩子来检测那些Angular自身无法捕获的变更并采取行动。
用这个方法来检测那些被Angular忽略的更改。
另外还要记住,在指令的构造函数完成之前,那些被绑定的输入属性还都没有值。 如果我们需要基于这些属性的值来初始化这个指令,这种情况就会出问题。 而当ngOnInit()执行的时候,这些属性都已经被正确的赋值过了。 - ngAfterContentInit
- ngAfterContentChecked
- ngAfterViewInit
- ngAfterViewChecked
3. 表单:
- 模板驱动表单:
- 添加FormModule 模块到@NgModule 元数据imports数组中,使得在整个应用的模板驱动表单中都可以使用特有的表单指令。
- 表单中使用[(ngModel)]指令进行数据绑定,使用ngModel时,必须为表单控件添加name属性:
NgModel指令实现了数据绑定,提供了表单控件状态的跟踪及校验功能。
- 表单的局部变量
这里#name绑定了ngModel,是对NgModel指令实例对象的引用,可以在模板中读取NgModel实例对象的属性值,可以追踪控件状态,表单校验不通过时提供错误信息。
- 控件状态
状态 | true/false |
---|---|
valid | 表单值是否有效 |
pristine | 表单值是否 未 改变 |
dirty | 表单值是否 已 改变 |
touched | 表单是否 已被 访问过 |
untouched | 表单是否 未被 访问过 |
- 自定义表单样式
NgModel指令不仅仅能追踪表单控件的状态,还会根据表单控件的状态使用对应的CSS状类更新表单控件类名。
状态 | true时的状态类 | false时的状态类 |
---|---|---|
控件是否已经被访问过 | ng-touched | ng-untouched |
控件值是否发生变化 | ng-dirty | ng-pristine |
控件值是否有效 | ng-valid | ng-invalid |
- 响应式表单
响应式表单和模板驱动表单都有自己的模块:ReactiveFormsModule
和 FormsModule
响应式表单是同步的。模板驱动表单是异步的。这个不同点很重要。
- FormControl
- FormGroup
- FormBuilder
- 明确把heroForm属性的类型声明为[FormGroup],稍后我们会初始化它。
- 把FormBuilder注入到构造函数中。
- 添加一个名叫createForm的新方法,它会用FormBuilder来定义heroForm。
- 在构造函数中调用createForm
- 多级FormGroup
constructor(private fb: FormBuilder) {
this.createForm();
}
createForm() {
this.heroForm = this.fb.group({ // <-- the parent FormGroup
name: ['', Validators.required ],
address: this.fb.group({ // <-- the child FormGroup
street: '',
city: '',
state: '',
zip: ''
}),
power: '',
sidekick: ''
});
- Validators验证器
- setValue、patchValue
- 动画
5. 服务:
- 组件的任务就是提供用户体验,仅此而已。它介于视图(由模板渲染)和应用逻辑(通常包括模型的某些概念)之间。 设计良好的组件为数据绑定提供属性和方法,把其它琐事都委托给服务。
组件类应保持精简。组件本身不从服务器获得数据、不进行验证输入,也不直接往控制台写日志。 它们把这些任务委托给服务。
6. 依赖注入:
7. 路由:
- 只在根模块AppRoutingModule中调用RouterModule.forRoot(如果在AppModule中注册应用的顶级路由,那就在AppModule中调用)。 在其它模块中,我们就必须调用RouterModule.forChild方法来注册附属路由。
- 路由策略
- ng2默认路由策略使用的是PathLocationStrategy,要使用此路由策略必须满足三个条件:
(1) 浏览器支持HTML5的histroy.pushState()
(2) 需要在服务器进行设置,将应用的所有URL重定向到应用首页。
(3) 需要为应用设置base路径
第二条就是我把demo放到服务器上后刷新页面返回404的原因。
解决方案:使用HashLocationStrategy路由策略。 - HashLocationStrategy策略
(1) 浏览器向服务器发送请求时不会带上hash部分内容,浏览器向服务器发送的请求都为同一个,服务器只需要返回相应的首页,Angular在获取首页后会根据hash的内容去匹配路由配置项并渲染相应的组件。
如何使用?
app.module.ts中
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
...
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
8. 测试:
二、引入ngx-bootstrap
1.安装bootstrap和ngx-bootstrap
npm install ngx-bootstrap bootstrap --save
2.进入项目根模块中
import { xModule } from 'ngx-bootstrap';
@NgModule({
imports: [xModule.forRoot(), ... ],
})
x Module 是你需要什么ngx-bootstrap里面的模块就导入什么
具体模块见:ngx-bootstrap
3.打开 .angular-cli.json 在styles中输入
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"styles.css",
],
或 在styles.css中import
@import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
ngx-bootstrap是基于bootstrap 开发的适用于angularjs的UI库,所以需要导入bootstrap.min.css
4.打开需要用到的组件模板页面
添加你需要的ngx-bootstrap的组件模板
三、编译
ng build --prod --aot
加上--prod参数之后,angular-cli会自动启用TreeShaking(摇树)特性,简而言之,就是把用不到的包全部剔除掉,就像从树上把枯叶子摇下来一样,很形象吧?加上--aot参数是让angular-cli启动预编译特性。
为什么需要AOT编译?
- 渲染得更快
使用AOT,浏览器下载预编译版本的应用程序。 浏览器直接加载运行代码,所以它可以立即渲染该应用,而不用等应用完成首次编译。 - 需要的异步请求更少
编译器把外部HTML模板和CSS样式表内联到了该应用的JavaScript中。 消除了用来下载那些源文件的Ajax请求。 - 需要下载的Angular框架体积更小
如果应用已经编译过了,自然不需要再下载Angular编译器了。 该编译器差不多占了Angular自身体积的一半儿,所以,省略它可以显著减小应用的体积。 - 提早检测模板错误
AOT编译器在构建过程中检测和报告模板绑定错误,避免用户遇到这些错误。 - 更安全
AOT编译远在HTML模版和组件被服务到客户端之前,将它们编译到JavaScript文件。 没有模版可以阅读,没有高风险客户端HTML或JavaScript可利用,所以注入攻击的机会较少。