theme: fancy
全局安装脚手架
npm install -g @angular/cli
创建项目
ng new my-app
cd my-app
ng serve --open
创建组件
1.在终端窗口中,导航到要放置你应用的目录
2.运行 ng generate component <component-name>
命令,其中 <component-name>
是新组件的名字
组件内容
该命令会创建以下内容
- 一个以该组件命名的文件夹
- 一个组件文件
<component-name>.component.ts
- 一个模板文件
<component-name>.component.html
- 一个 CSS 文件,
<component-name>.component.css
- 测试文件
<component-name>.component.spec.ts
生命周期
钩子方法 | 用途 | 时机 |
---|---|---|
ngOnChanges() |
Respond when Angular sets or resets data-bound input properties. The method receives a SimpleChanges object of current and previous property values. NOTE: This happens very frequently, so any operation you perform here impacts performance significantly. See details in Using change detection hooks in this document.当 Angular 设置或重新设置数据绑定的输入属性时响应。该方法接受当前和上一属性值的 SimpleChanges 对象注意: 这发生的非常频繁,所以你在这里执行的任何操作都会显著影响性能。欲知详情,参阅本文档的使用变更检测钩子。 |
Called before ngOnInit() (if the component has bound inputs) and whenever one or more data-bound input properties change. NOTE: If your component has no inputs or you use it without providing any inputs, the framework will not call ngOnChanges() . 如果组件绑定过输入属性,那么在 ngOnInit() 之前以及所绑定的一个或多个输入属性的值发生变化时都会调用。注意: 如果你的组件没有输入属性,或者你使用它时没有提供任何输入属性,那么框架就不会调用 ngOnChanges() 。 |
ngOnInit() |
在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。欲知详情,参阅本文档中的初始化组件或指令。 | 在第一轮 ngOnChanges() 完成之后调用,只调用一次。而且即使没有调用过 ngOnChanges() ,也仍然会调用 ngOnInit() (比如当模板中没有绑定任何输入属性时)。 |
ngDoCheck() |
检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应。欲知详情和范例,参阅本文档中的自定义变更检测。 | 紧跟在每次执行变更检测时的 ngOnChanges() 和 首次执行变更检测时的 ngOnInit() 后调用。 |
ngAfterContentInit() |
当 Angular 把外部内容投影进组件视图或指令所在的视图之后调用。 欲知详情和范例,参阅本文档中的响应内容中的变更。 | 第一次 ngDoCheck() 之后调用,只调用一次。 |
ngAfterContentChecked() |
每当 Angular 检查完被投影到组件或指令中的内容之后调用。 欲知详情和范例,参阅本文档中的响应被投影内容的变更。 | ngAfterContentInit() 和每次 ngDoCheck() 之后调用。 |
ngAfterViewInit() |
当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用。 欲知详情和范例,参阅本文档中的响应视图变更。 | 第一次 ngAfterContentChecked() 之后调用,只调用一次。 |
ngAfterViewChecked() |
每当 Angular 做完组件视图和子视图或包含该指令的视图的变更检测之后调用。 | ngAfterViewInit() 和每次 ngAfterContentChecked() 之后调用。 |
ngOnDestroy() |
每当 Angular 每次销毁指令/组件之前调用并清扫。在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。欲知详情,参阅本文档中的在实例销毁时进行清理。 | 在 Angular 销毁指令或组件之前立即调用。 |
## 组件的封装 |
- 如果是使用代码去生成组件的话,代码和引入操作,都会自动帮我们去完成,
@selector
里面的内容相当于组件名称,直接可以当成组件去引入
插值表达式
// hello-world.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-hello-world',
template: '<h1> {{title}} </h1>',
styles: ['h1 { color: red; }']
})
export class HelloWorldComponent {
public title = '学习Angular第一课';
}
- {{}} 里去动态替换template里面的内容
内置指令
NgClass
动态添加和删除一组css类NgStyle
: 动态添加和删除一组内联样式NgModel
: 将数据的双向绑定添加到HTML表单元素上NgFor
: 重复循环渲染某一个节点
// 其实除了常用的index,ngFor还提供了其他的一些局部变量,我们可以通过给局部变量起别名从而来使用它
//常用变量如下: (index: number; count: nuber; first: boolean; last: boolean; even: boolean,odd: boolean)
NgIf
: 从模板中创建或销毁子视图,通俗说是控制组件或者元素的显示和隐藏NgSwitch
: 类似于js中的switch的逻辑,也是按照满足固定的条件显示某些模板/视图
NgSwitch是一组属性(三个) 分别是: `NgSwitch`; `NgSwitchCase`; `ngSwitchDefault`
- 绑定到class的Attribute
<div [class.textcolor]="isSingleClass">尝试绑定单个class</div> <div [class]="multipleClass">尝试绑定多个class</div>
public isSingleClass: boolean; public multipleClass = { // 所以这里生效的只有bgColor这个类 bgColor: true, textcolor: false, };
管道
-
DatePipe
:根据本地环境中的规则格式化日期值。 -
UpperCasePipe
:把文本全部转换成大写。 -
LowerCasePipe
:把文本全部转换成小写。 -
CurrencyPipe
:把数字转换成货币字符串,根据本地环境中的规则进行格式化。 -
DecimalPipe
:把数字转换成带小数点的字符串,根据本地环境中的规则进行格式化。 -
PercentPipe
:把数字转换成百分比字符串,根据本地环境中的规则进行格式化。
<p>小明的生日是{{ birthday | date }}</p> <p>小明的生日是{{ birthday | date:"MM/dd/yy" }}</p>
//结果 小明的生日是Apr 15, 1988 小明的生日是04/15/88
事件绑定
public nums = 1
public add(num:number) {
this.nums+= num
}
{{nums}}
<button (click)="add(1)">add</button>
父子组件传值
父到子
// app-outside-introduction是app.component的子组件,现在通过这个组件来学习一下父子传值
// outside-introduction.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-outside-introduction',
templateUrl: './outside-introduction.component.html',
styleUrls: ['./outside-introduction.component.scss']
})
export class OutsideIntroductionComponent {
// @Input()是专门用来实现传值的,需要提前在'@angular/core引入
// 这句声明,表示希望在父组件引入子组件的html页面中,从父组件中传入一个值给到showNumber
@Input() public showNumber: number;
}
// outside-introduction.component.html
<div>显示父组件传进来的值{{showNumber}}</div>
// 父组件app.component.html
<div>父组件中的值:{{defaultNum}}</div>
<app-outside-introduction [showNumber]="defaultNum"></app-outside-introduction>
// 父组件app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
public defaultNum = 5;
}
子到父
// 子组件
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-outside-introduction',
templateUrl: './outside-introduction.component.html',
styleUrls: ['./outside-introduction.component.scss']
})
export class OutsideIntroductionComponent {
@Input() public showNumber: number;
// 下边的逻辑主要实现自组价向父组件emit一个值
@Output() public curCountChange = new EventEmitter<number>();
public curCount = 1;
public addCount(): void {
this.curCount++;
this.curCountChange.emit(this.curCount);
}
}
// 父组件
// 这里的事件名curCountChange必须和子组件定义@Output()的名字是一样的,=后边的方法名可以自己随意定义
// `$event`是子组件传过来的值
<app-outside-introduction [showNumber]="defaultNum" (curCountChange)="handlCurCountChange($event)"></app-outside-introduction>
public handlCurCountChange(value: number): void {
// 这里的value就是子组件传过来的值
this.valueFromChild = value;
}
@Output()
- 一个装饰器函数,它把该属性标记为数据从子组件进入父组件的一种途径curCountChange
- 这个@Output()
的名字EventEmitter<number>
- 这个@Output()
的类型,就是子组件传给父组件的数据类型new EventEmitter<number>()
- 使用 Angular 来创建一个新的事件发射器,它发出的数据是number
类型的。curCountChange.emit()
- 通过emit方法来向父组件传递值 最终父组件通过事件的形式接受子组件穿过来的值
双向绑定
表单双向绑定
import { FormsModule } from '@angular/forms'
imports: [
BrowserModule,
FormsModule
],
{{name}}
<input type="text" [(ngModel)]="name">
组件双向绑定
父组件
fatherToFather-----------{{nums}}
<button (click)="add()">add</button>
<app-demo1 [(nums)]="nums"></app-demo1>
nums = 1
add() {
this.nums++
}
子组件
fatherToChild-----{{nums}}
<button (click)="reduce()">reduce</button>
@Input() nums: number | undefined
@Output() numsChange = new EventEmitter()
reduce() {
if(typeof this.nums === 'number') {
this.nums--
this.numsChange.emit(this.nums)
}
}