angular 入门

283 阅读6分钟

全局安装脚手架

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 销毁指令或组件之前立即调用。

组件的封装

image.png

image.png

image.png

image.png

  • 如果是使用代码去生成组件的话,代码和引入操作,都会自动帮我们去完成,@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里面的内容

内置指令

  1. NgClass 动态添加和删除一组css类
  2. NgStyle: 动态添加和删除一组内联样式
  3. NgModel: 将数据的双向绑定添加到HTML表单元素上
  4. NgFor: 重复循环渲染某一个节点

image.png

// 其实除了常用的index,ngFor还提供了其他的一些局部变量,我们可以通过给局部变量起别名从而来使用它
//常用变量如下: (index: number; count: nuber; first: boolean; last: boolean;  even: boolean,odd: boolean)
  1. NgIf: 从模板中创建或销毁子视图,通俗说是控制组件或者元素的显示和隐藏
  2. NgSwitch: 类似于js中的switch的逻辑,也是按照满足固定的条件显示某些模板/视图
NgSwitch是一组属性(三个) 分别是: `NgSwitch``NgSwitchCase``ngSwitchDefault`
  1. 绑定到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)
    }
  }