2

Angular7入门总结篇

一、Angular 介绍

  • 根据项目数统计 angular(1.x 、2.x 、4.x、5.x、6.x、7.x)是现在网上使用量最大的框架
  • Angualr 基于 TypeScript 和 reactvue 相比, Angular 更适合中大型企业级项目。
目前 2018 年 11 月 25 日 angular 最新版本 angular7.x。根据官方介绍,Angular 每过几个月 就会更新一个版本。此教程同样适用于后期更新的 Angular8.xAngular9.x

image

学习 Angular 必备基础

必备基础:html 、css 、jses6Typescript

二、Angular 环境搭建及创建项目

1 环境搭建

1. 安装 nodejs

安装 angular 的计算机上面必须安装最新的 nodejs--注意安装 nodejs 稳定版本

</article>

augury查看component结构,更方便调试

image

2.3 目录结构分析

image

app目录(重点)

app目录是我们要编写的代码目录。我们写的代码都是放在这个目录。
一个Angular程序至少需要一个模块和一个组件。在我们新建项目的时候命令行已经默认生成出来了

image

  • app.component.ts:这个文件表示组件,
  • 组件是Angular应用的基本构建模块,可以理解为一段带有业务逻辑和数据的Html
    我们来看看app.component.ts中的代码,并解释下代码的意义

image

2.4 Angular cli

1. 创建新组件 ng generate component component-name

ng g component components/header 指定生成到哪个目录

该命令会把生成的组件,添加到 src/app/app.module.ts 文件中 @NgModule 的 declarations 列表中声明

image

三、angular组件及组件里的模板

3.1 创建angualr组件

1. 创建组件

ng g component components/header

2. 使用组件

<app-header></app-header>

3.2 Angular 绑定数据

1. 数据文本绑定

定义数据几种方式

image

<h1>{{title}}</h1>

2. 绑定HTML

 this.h="<h2>这是一个 h2 用[innerHTML]来解析</h2>"
 <div [innerHTML]="h"></div>

3.3 声明属性的几种方式

  • public 共有(默认) 可以在类里外使用
  • protected 保护类型 只能在当前类和子类中使用
  • private 私有类型 只能在当期类使用

3.4 绑定属性

[]包裹
 <div [id]="id" [title]="msg">调试工具看看我的属性</div>

image

3.5 数据循环 *ngFor

1. *ngFor 普通循环

export class HomeComponent implements OnInit {

  arr = [{ name: 'poetries', age: 22 }, { name: 'jing' , age: 31}];
  constructor() { }

  ngOnInit() {
  }

}
<ul *ngIf="arr.length>0">
      <li *ngFor="let item of arr">{{item.name}}- {{item.age}}</li>
</ul>

2. 循环的时候设置 key

<ul>
<li *ngFor="let item of list;let i = index;"> <!-- 把索引index赋给i -->
     {{item}} --{{i}}
</li> </ul>

3. template 循环数据

<ul>
  <li template="ngFor let item of list">
{{item}}
</li> </ul>

3.6 条件判断 *ngIf

<p *ngIf="list.length > 3">这是 ngIF 判断是否显示</p>

<p template="ngIf list.length > 3">这是 ngIF 判断是否显示</p>

3.7 *ngSwitch

<ul [ngSwitch]="score">
<li *ngSwitchCase="1">已支付</li>
<li *ngSwitchCase="2">订单已经确认</li> <li *ngSwitchCase="3">已发货</li>
<li *ngSwitchDefault>无效</li>
</ul>

3.8 执行事件 (click)=”getData()”

<button class="button" (click)="getData()"> 点击按钮触发事件
</button>
<button class="button" (click)="setData()"> 点击按钮设置数据
</button>
getData(){ /*自定义方法获取数据*/ //获取
  alert(this.msg);
} 
setData(){
    //设置值
    this.msg='这是设置的值';
}

3.9 表单事件

<input
type="text"
(keyup)="keyUpFn($event)"/>

<input type="text" (keyup)="keyUpFn($event)"/>
keyUpFn(e){
    console.log(e)
}

3.10 双向数据绑定

<input [(ngModel)]="inputVal">
注意引入:FormsModule
import {FormsModule} from '@angular/forms'

NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    NewsComponent
  ], 
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
<!--使用-->
<input type="text" [(ngModel)]="inputValue"/> {{inputValue}}

3. 11 [ngClass]、[ngStyle]

1. [ngClass]:

<div [ngClass]="{'red': true, 'blue': false}"> 
    这是一个 div
</div>
public flag=false;
<div [ngClass]="{'red': flag, 'blue': !flag}">
这是一个 div </div>
public arr = [1, 3, 4, 5, 6];
<ul>
<li *ngFor="let item of arr, let i = index"> <span [ngClass]="{'red': i==0}">{{item}}</span>
</li> </ul>

2. [ngStyle]:

<div [ngStyle]="{'background-color':'green'}">你好 ngStyle</div>
public attr='red';
<div [ngStyle]="{'background-color':attr}">你好 ngStyle</div>

3.12 管道

 public today=new Date();
 <p>{{today | date:'yyyy-MM-dd HH:mm:ss' }}</p>

其他管道

angular中的管道(pipe)是用来对输入的数据进行处理,如大小写转换、数值和日期格式化等

angular中的管道(pipe) 以及自定义管道适用于angular4 angualr5 angualr6 angular7

常用的管道(pipe)有

1. 大小写转换

<!--转换成大写-->
<p>{{str | uppercase}}</p>

<!--转换成小写-->
<p>{{str | lowercase}}</p>

2. 日期格式转换

<p>
{{today | date:'yyyy-MM-dd HH:mm:ss' }}
</p> 

3. 小数位数

接收的参数格式为{最少整数位数}.{最少小数位数}-{最多小数位数}
<!--保留2~4位小数-->

<p>{{p | number:'1.2-4'}}</p> 

4. JavaScript 对象序列化

<p>
    {{ { name: 'semlinker' } | json }}
</p> 
<!-- Output: { "name": "semlinker" } -->

5. slice

<p>{{ 'semlinker' | slice:0:3 }}</p> 
<!-- Output: sem -->

6. 管道链

<p>
{{ 'semlinker' | slice:0:3 | uppercase }}
</p> 

<!-- Output: SEM -->

7. 自定义管道

自定义管道的步骤:

  • 使用 @Pipe 装饰器定义 Pipe 的 metadata 信息,如 Pipe 的名称 - 即 name 属性
  • 实现 PipeTransform 接口中定义的 transform 方法

7.1 WelcomePipe 定义

import { Pipe, PipeTransform } from '@angular/core';

[@Pipe](/user/Pipe)({ name: 'welcome' })

export class WelcomePipe implements PipeTransform {
  transform(value: string): string {
    if(!value) return value;
    if(typeof value !== 'string') {
      throw new Error('Invalid pipe argument for WelcomePipe');
    }
    return "Welcome to " + value;
  }
} 

7.2 WelcomePipe 使用

<div>
   <p ngNonBindable>{{ 'semlinker' | welcome }}</p>
   <p>{{ 'semlinker' | welcome }}</p> <!-- Output: Welcome to semlinker -->
</div>

四、Angular 中的服务

4.1 服务

定义公共的方法,使得方法在组件之间共享调用

image

1. 创建服务命令

ng g service my-new-service

# 创建到指定目录下面
ng g service services/storage

2. app.module.ts 里面引入创建的服务

// app.module.ts 里面引入创建的服务

import { StorageService } from './services/storage.service';
// NgModule 里面的 providers 里面依赖注入服务

NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    NewsComponent,
    TodolistComponent
], imports: [
    BrowserModule,
FormsModule
  ],
  providers: [StorageService],
  bootstrap: [AppComponent]
})
export class AppModule { }

3. 使用的页面引入服务,注册服务

 import { StorageService } from '../../services/storage.service';
 constructor(private storage: StorageService) {

 }
// 使用

addData(){
     // alert(this.username);
    this.list.push(this.username); 
    this.storage.set('todolist',this.list);
}
removerData(key){
    console.log(key); 
    this.list.splice(key,1); 
    this.storage.set('todolist',this.list);
}

五、Dom 操作以及@ViewChild、 执行 css3 动画

1. Angular 中的 dom 操作(原生 js)

ngAfterViewInit(){
var boxDom:any=document.getElementById('box'); boxDom.style.color='red';
}

2. Angular 中的 dom 操作(ViewChild)

 import { Component ,ViewChild,ElementRef} from '@angular/core';
 @ViewChild('myattr') myattr: ElementRef;
<div #myattr></div>
ngAfterViewInit(){
let attrEl = this.myattr.nativeElement;
}

3. 父子组件中通过 ViewChild 调用子组件 的方法

调用子组件给子组件定义一个名称
<app-footer #footerChild></app-footer>
引入 ViewChild
 import { Component, OnInit ,ViewChild} from '@angular/core';
ViewChild 和刚才的子组件关联起来
 @ViewChild('footerChild') footer
在父组件中调用子组件方法
 run(){ 
    this.footer.footerRun();
}

六、Angular 父子组件以及组件之间通讯

image

6.1 父组件给子组件传值-@input

父组件不仅可以给子组件传递简单的数据,还可把自己的方法以及整个父组件传给子组件

1. 父组件调用子组件的时候传入数据

<app-header [msg]="msg"></app-header>

2. 子组件引入 Input 模块

import { Component, OnInit ,Input } from '@angular/core';

3. 子组件中 @Input 接收父组件传过来的数据

export class HeaderComponent implements OnInit {
  @Input() msg:string

  constructor() { }

  ngOnInit() {
  }
}

4. 子组件中使用父组件的数据

<p>
  child works!
  {{msg}}
</p>

5. 把整个父组件传给子组件

通过this传递整个组件实例
<app-header [home]="this"></app-header>
export class HeaderComponent implements OnInit {
  @Input() home:any

  constructor() { }

  ngOnInit() {
  }
}
执行父组件方法 this.home.xxx()

6.2 子组件通过@Output 触发父组件的方法(了解)

1. 子组件引入 Output 和 EventEmitter

 import { Component, OnInit ,Input,Output,EventEmitter} from '@angular/core';

2. 子组件中实例化 EventEmitter

@Output() private outer=new EventEmitter<string>(); /*用EventEmitter和output装饰器配合使用 <string>指定类型变量*/

3. 子组件通过 EventEmitter 对象 outer 实例广播数据

sendParent(){
  // alert('zhixing');
  this.outer.emit('msg from child')
}

6.4 非父子组件通讯

  • 公共的服务
  • Localstorage (推荐)
  • Cookie

七、Angular 中的生命周期函数

7.1 Angular中的生命周期函数

官方文档:https://www.angular.cn/guide/lifecycle-hooks
  • 生命周期函数通俗的讲就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。
  • 当 Angular 使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些 生命周期钩子方法。
  • 每个接口都有唯一的一个钩子方法,它们的名字是由接口名再加上ng前缀构成的,比如OnInit接口的钩子方法叫做ngOnInit.

1. 生命周期钩子分类

基于指令与组件的区别来分类

指令与组件共有的钩子

  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngOnDestroy

组件特有的钩子

  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked

image

2. 生命周期钩子的作用及调用顺序

1、ngOnChanges - 当数据绑定输入属性的值发生变化时调用
2、ngOnInit - 在第一次 ngOnChanges 后调用
3、ngDoCheck - 自定义的方法,用于检测和处理值的改变
4、ngAfterContentInit - 在组件内容初始化之后调用
5、ngAfterContentChecked - 组件每次检查内容时调用
6、ngAfterViewInit - 组件相应的视图初始化之后调用
7、ngAfterViewChecked - 组件每次检查视图时调用
8、ngOnDestroy - 指令销毁前调用
3. 首次加载生命周期顺序

export class LifecircleComponent {

    constructor() {

        console.log('00构造函数执行了---除了使用简单的值对局部变量进行初始化之外,什么都不应该做')
    }

    ngOnChanges() {

        console.log('01ngOnChages执行了---当被绑定的输入属性的值发生变化时调用(父子组件传值的时候会触发)'); 
    }

    ngOnInit() {
        console.log('02ngOnInit执行了--- 请求数据一般放在这个里面');
    }
    ngDoCheck() {
        console.log('03ngDoCheck执行了---检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应');
    }
    ngAfterContentInit() {
        console.log('04ngAfterContentInit执行了---当把内容投影进组件之后调用');
    }
    ngAfterContentChecked() {
        console.log('05ngAfterContentChecked执行了---每次完成被投影组件内容的变更检测之后调用');
    }
    ngAfterViewInit() : void {
        console.log('06 ngAfterViewInit执行了----初始化完组件视图及其子视图之后调用(dom操作放在这个里面)');
    }
    ngAfterViewChecked() {
        console.log('07ngAfterViewChecked执行了----每次做完组件视图和子视图的变更检测之后调用');
    }

    ngOnDestroy() {
        console.log('08ngOnDestroy执行了····');
    }

    //自定义方法
    changeMsg() {

        this.msg = "数据改变了";
    }
}

7.2.7 ngAfterViewInit()--掌握

初始化完组件视图及其子视图之后调用。第一 次 ngAfterContentChecked() 之后调用,只调用一次。在这里可以操作DOM

7.2.9 ngOnDestroy()--掌握

当 Angular 每次销毁指令/组件之前调用并清扫。在这儿反订阅可观察对象和分离事件处理器,以防内存泄 漏。在 Angular 销毁指令/组件之前调用。比如:移除事件监听、清除定时器、退订 Observable 等。
@Directive({
    selector: '[destroyDirective]'
})
export class OnDestroyDirective implements OnDestroy {
  sayHello: number;

  constructor() {
    this.sayHiya = window.setInterval(() => console.log('hello'), 1000);
  }

  ngOnDestroy() {
     window.clearInterval(this.sayHiya);
  }
}

八、Rxjs 异步数据流编程

8.1 Rxjs介绍

  • RxJS 是一种针对异步数据流编程工具,或者叫响应式扩展编程;可不管如何解释 RxJS 其目 标就是异步编程,Angular 引入 RxJS 为了就是让异步可控、更简单。
  • RxJS 里面提供了很多模块。这里我们主要给大家讲 RxJS 里面最常用的Observable 和 fromEvent

目前常见的异步编程的几种方法:

  • 回调函数
  • 事件监听/发布订阅
  • Promise
  • Rxjs

8.3 Rxjs unsubscribe 取消订阅

Promise 的创建之后,动作是无法撤回的。Observable 不一样,动作可以通过 unsbscribe() 方法中途撤回,而且 Observable 在内部做了智能的处理.

Promise 创建之后动作无法撤回

九、路由

// 引入组件

import { HomeComponent } from './home/home.component';
import { NewsComponent } from './news/news.component';
import { NewscontentComponent } from './newscontent/newscontent.component';

// 配置路由
const routes: Routes = [
  {path: 'home', component: HomeComponent},
  {path: 'news', component: NewsComponent},
  {path: 'newscontent/:id', component: NewscontentComponent},
  {
    path: '',
    redirectTo: '/home',
    pathMatch: 'full'
} ];

WInd
21 声望3 粉丝

追梦的少年