angular 8 学习记录



1,安装Angular Cli、创建运行Angular项目

安装cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org

2、使用 npm/cnpm 命令安装angular/cli (只需要安装一次)

npm install -g @angular/cli 或者 cnpm install -g @angular/cli

四、Angular创建项目

直接安装:

ng new angulardemo

如果要跳过npm i安装:

ng new angulardemo --skip-install

  1. 运行项目

cd angulardemo

ng serve --open



1,Angular 目录结构分析

Angular 目录结构分析
在这里插入图片描述

== app.module.ts ==

在这里插入图片描述

自定义组件

  • 创建组件:ng g component components/header

  • 组件内容详解:

import { Component, OnInit } from '@angular/core'; /*引入 angular 核心*/ 
@Component({ 
	selector: 'app-header', /*使用这个组件的名称*/ 
	templateUrl: './header.component.html', /*html 模板*/ 
	styleUrls: ['./header.component.css'] /*css 样式*/ 
})
export class HeaderComponent implements OnInit { /*实现接口*/ 
	constructor() { }  /*构造函数*/ 
	ngOnInit() { }    /*初始化加载的生命周期函数*/
}

Angular 中使用{{}}绑定业务逻辑里面定义的数据



3,angular 组件 以及组件里面的模板

== 一、创建 angualr 组件==

创建组件 ng g component components/header
使用组件 <app-header></app-header>

二、Angular 绑定数据

  1. 数据文本绑定 {{}}
<h1> {{title}} </h1> 

<div> 1+1={{1+1}} </div>
  1. 绑定 html
this.h="<h2>这是一个 h2 用[innerHTML]来解析</h2>" 

<div [innerHTML]="h"></div>

二、绑定属性

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

在这里插入图片描述

三、数据循环 *ngFor

  • 1、*ngFor 普通循环
<ul>
	<li *ngFor="let item of list"> {{item}} </li> 
</ul>
  • 2、循环的时候设置 key
<ul>
	<li *ngFor="let item of list;let i = index;"> 
		{{item}} --{{i}} 
	</li> 
</ul>
    1. template 循环数据
<ul>
	<li template="ngFor let item of list"> 
		{{item}} 
	</li> 
</ul>

四、条件判断 *ngIf

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

四、*ngSwitch

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

五、执行事件 (click)=”getData()”

<button class="button" (click)="getData()"> 点击按钮触发事件 </button> 
<button class="button" (click)="setData()"> 点击按钮设置数据 </button> 


getData(){  alert(this.msg); }   /*自定义方法获取数据*/
setData(){  this.msg='这是设置的值'; }

七、表单事件

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


keyUpFn(e){ 
	console.log(e) 
}

八、双向数据绑定

  • 引入: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}}

九、[ngClass]、[ngStyle]

  • [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>
  • [ngStyle]:
<div [ngStyle]="{'background-color':'green'}">你好 ngStyle</div> 

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

十、管道

public today=new Date(); 

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

其他管道: http://bbs.itying.com/topic/5bf519657e9f5911d41f2a34

Angualr 中的服务

创建服务命令

ng g service my-new-service 

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

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

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

import { StorageService } from './services/storage.service';

    1. NgModule 里面的 providers 里面依赖注入服务
@NgModule({ 
	declarations: [ AppComponent, HeaderComponent, FooterComponent, NewsComponent, TodolistComponent ],
	imports: [ BrowserModule, FormsModule ],
	providers: [StorageService], 
	bootstrap: [AppComponent] 
})
export class AppModule { }

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

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、 Angular 执行 css3 动画

Angular 中的 dom 操作(原生 js)

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

Angular 中的 dom 操作(ViewChild)

引入:
import { Component ,ViewChild,ElementRef} from '@angular/core';

@ViewChild('myattr') myattr: ElementRef;

<div #myattr> </div>

ngAfterViewInit(){ 
	let attrEl = this.myattr.nativeElement; 
}

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

  1. 调用子组件给子组件定义一个名称

<app-footer #footerChild></app-footer>

  1. 引入 ViewChild

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

  1. ViewChild 和刚才的子组件关联起来

@ViewChild('footerChild') footer;

  1. 调用子组件
run(){
	this.footer.footerRun(); 
}


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

== 一、父组件给子组件传值-@input ==

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

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

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

  1. 子组件引入 Input 模块

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

  1. 子组件中 @Input 接收父组件传过来的数据
export class HeaderComponent implements OnInit { 
	@Input() msg:string
	constructor() { } 
	ngOnInit() { } 
}
  1. 子组件中使用父组件的数据

<h2>这是头部组件--{{msg}}</h2>

子组件通过@Output 触发父组件的方法

  1. 子组件引入 Output 和 EventEmitter

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

  1. 子组件中实例化 EventEmitter
@Output() private outer=new EventEmitter<string>(); 

/*用 EventEmitter 和 output 装饰器配合使用 <string>指定类型变量*/ 
  1. 子组件通过 EventEmitter 对象 outer 实例广播数据
sendParent(){ 
	// alert('zhixing'); 
	this.outer.emit('msg from child') 
}
  1. 父组件调用子组件的时候,定义接收事件 , outer 就是子组件的 EventEmitter 对象 outer

<app-header (outer)="runParent($event)"></app-header>

  1. 父组件接收到数据会调用自己的 runParent 方法,这个时候就能拿到子组件的数据
//接收子组件传递过来的数据 
runParent(msg:string){ 
	alert(msg); 
}

父组件通过@ViewChild 主动获取子组件的数据和方法

  1. 调用子组件给子组件定义一个名称

<app-footer #footerChild></app-footer>

  1. 引入 ViewChild

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

  1. ViewChild 和刚才的子组件关联起来

@ViewChild('footerChild') footer;

  1. 调用子组件
run(){ 
	this.footer.footerRun();
}

四、非父子组件通讯

1、公共的服务
2、Localstorage (推荐)
3、Cookie



Angular 中的生命周期函数

生命周期函数通俗的讲就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。

当 Angular 使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些 生命周期钩子方法。

constructor

构造函数中除了使用简单的值对局部变量进行初始化 之外,什么都不应该做。 (非生命周期函数)

ngOnChanges()

当 Angular(重新)设置数据绑定输入属性时响应。
该方法接受当前和上一属性值的 SimpleChanges 对象
当被绑定的输入属性的值发生变化时调用,首次调用一 定会发生在 ngOnInit() 之前。

*** ngOnInit()

在 Angular 第一次显示数据绑定和设置指令/组件的输 入属性之后,初始化指令/组件。

在第一轮 ngOnChanges() 完成之后调用,只调用一次。

  • 使用 ngOnInit() 有两个原因:
  1. 在构造函数之后马上执行复杂的初始化逻辑

  2. 在 Angular 设置完输入属性之后,对该组件进行准备

ngDoCheck()

检测,并在发生 Angular 无法或不愿意自己检测的变 化时作出反应。

在每个 Angular 变更检测周期中调用, ngOnChanges() 和 ngOnInit() 之后。

ngAfterContentInit()

当把内容投影进组件之后调用。第一次 ngDoCheck() 之 后调用,只调用一次。

ngAfterContentChecked()

每次完成被投影组件内容的变更检测之后调用。
ngAfterContentInit() 和每次 ngDoCheck() 之后调用。

*** ngAfterViewInit()

初 始 化 完 组 件 视 图 及 其 子 视 图 之 后 调 用 。
第 一 次 ngAfterContentChecked() 之后调用,只调用一次。

ngAfterViewChecked()

每次做完组件视图和子视图的变更检测之后调用。
ngAfterViewInit()和每次 ngAfterContentChecked() 之后 调用

*** ngOnDestroy()

当 Angular 每次销毁指令/组件之前调用并清扫。在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。

在 Angular 销毁指令/组件之前调用。



Rxjs 异步数据流编程

RxJS 是一种针对异步数据流编程工具,或者叫响应式扩展编程

它将一切数据,包括 HTTP 请求,DOM 事件或者普通数据等包装成流 的形式,然后用强大丰富的操作符对流进行处理,使你能以同步编程的方式处理异步数据, 并组合不同的操作符来轻松优雅的实现你所需要的功能

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

1、回调函数
2、事件监听/发布订阅
3、Promise
4、Rxjs

Promise 和 RxJS 处理异步对比

  • Promise 处理异步:
let promise = new Promise(resolve => { 
	setTimeout(() => { 
			resolve('---promise timeout---'); 
		}, 2000); 
	}); 
promise.then(value => console.log(value));
  • RxJS 处理异步
import {Observable} from 'rxjs'; 
let stream = new Observable(observer => { 
	setTimeout(() => { 
			observer.next('observable timeout'); 
		}, 2000); 
	}); 
stream.subscribe(value => console.log(value));

Promise 里面用的是 then() 和 resolve(),
而 RxJS 里面用的是 next() 和 subscribe()

其实Rxjs相比Promise 要强大很多。 比如 Rxjs 中可以中途撤回、Rxjs 可以发射多个值、Rxjs 提供了多种工具函数等等

Rxjs unsubscribe 取消订阅

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

let stream = new Observable(observer => { 
let timeout = setTimeout(() => { 
			clearTimeout(timeout); 
			observer.next('observable timeout'); 
		}, 2000); 
	}); 
let disposable = stream.subscribe(value => console.log(value)); 
setTimeout(() => { 
	//取消执行 
	disposable.unsubscribe(); 
}, 1000);

Rxjs 订阅后多次执行

对于 Promise 来说,最终结果要么 resole(兑现)、要么 reject (拒绝),而且都只能触发一次。如果在同一个 Promise 对象上多次调用 resolve 方法, 则会抛异常。
而 Observable 不一样,它可以不断地触发下一个值,就像 next() 这个方法的 名字所暗示的那样。

let stream = new Observable<number>(observer => { 
	let count = 0; 
	setInterval(() => { 
			observer.next(count++); 
		}, 1000); 
	}); 
stream.subscribe(value => console.log("Observable>"+value));

Angualr6.x 之前使用 Rxjs 的工具函数 map filter

注意:Angular6 以后使用以前的 rxjs 方法,必须安装 rxjs-compat 模块才可以使用 map、filter 方法。

angular6 后官方使用的是 RXJS6 的新特性,所以官方给出了一个可以暂时延缓我们不需要修 改 rsjx 代码的办法。

npm install rxjs-compat

import {Observable} from 'rxjs'; 
import 'rxjs/Rx';
let stream= new Observable<any>(observer => { 
	let count = 0; 
	setInterval(() => { 
			observer.next(count++); 
		}, 1000); 
	}); 

stream.filter(val=>val%2==0) 
	.subscribe(value => console.log("filter>"+value)); 

stream.map(value => { return value * value }) 
	.subscribe(value => console.log("map>"+value));

Angualr6.x 以后 Rxjs6.x 的变化以及 使用

RXJS6 改变了包的结构,主要变化在 import 方式和 operator 上面以及使用 pipe()

import {Observable} from 'rxjs'; 
import {map,filter} from 'rxjs/operators';
let stream= new Observable<any>(observer => {
		let count = 0; 
		setInterval(() => { observer.next(count++); }, 1000); 
	});

stream.pipe( 
		filter(val=>val%2==0) 
	) 
	.subscribe(value => console.log("filter>"+value)); 

stream.pipe( 
		filter(val=>val%2==0), 
		map(value => { return value * value }) 
	) 
	.subscribe(value => console.log("map>"+value));

Rxjs 延迟执行

import {Observable,fromEvent} from 'rxjs'; 
import {map,filter,throttleTime} from 'rxjs/operators'; 
var button = document.querySelector('button'); 
fromEvent(button, 'click').pipe( 
	throttleTime(1000) 
).subscribe(() => console.log(`Clicked`));


Angular 中的数据交互(get jsonp post)

一、Angular get 请求数据

Angular5.x 以后 get、post 和和服务器交互使用的是 HttpClientModule 模块。

1、在 app.module.ts 中引入 HttpClientModule 并注入

import {HttpClientModule} from '@angular/common/http';

imports: [ BrowserModule, HttpClientModule ]

2、在用到的地方引入 HttpClient 并在构造函数声明

import {HttpClient} from "@angular/common/http";

constructor(public http:HttpClient) { }

3、get 请求数据

var api = "http://a.itying.com/api/productlist"; 
this.http.get(api).subscribe(response => { 
	console.log(response); 
});

二、Angular post 提交数据

Angular5.x 以后 get、post 和和服务器交互使用的是 HttpClientModule 模块。

1、在 app.module.ts 中引入 HttpClientModule 并注入

import {HttpClientModule} from '@angular/common/http';

imports: [ BrowserModule, HttpClientModule ]

2、在用到的地方引入 HttpClient、HttpHeaders 并在构造函数声明 HttpClient

import {HttpClient,HttpHeaders} from "@angular/common/http";

constructor(public http:HttpClient) { }

3、post 提交数据

const httpOptions = { 
	headers: new HttpHeaders({ 'Content-Type': 'application/json' }) 
};
var api = "http://127.0.0.1:3000/doLogin"; 

this.http.post(api,{username:'张三',age:'20'}, httpOptions)
	.subscribe(response => { console.log(response); });

三、Angular Jsonp 请求数据

1、在 app.module.ts 中引入 HttpClientModule、HttpClientJsonpModule 并注入

import {HttpClientModule, HttpClientJsonpModule} from '@angular/common/http';

imports: [ BrowserModule, HttpClientModule, HttpClientJsonpModule ]

2、在用到的地方引入 HttpClient 并在构造函数声明

import {HttpClient} from "@angular/common/http";

constructor(public http:HttpClient) { }

3、jsonp 请求数据

var api = "http://a.itying.com/api/productlist"; 
this.http.jsonp(api,'callback')
	.subscribe(response => { console.log(response); });

四、Angular 中使用第三方模块 axios 请求数据

1、安装

axios cnpm install axios --save

2、用到的地方引入 axios

import axios from 'axios';

3、看文档使用

axios.get('/user?ID=12345') 
	.then(function (response) { 
		// handle success 
		console.log(response); 
	})
	.catch(function (error) { 
		// handle error 
		console.log(error); 
	})
	.then(function () { 
		// always executed 
	});


Angular 中的路由

一、Angular 创建一个默认带路由的项目

  1. 命令创建项目

ng new angualrdemo08 --skip-install

  1. 创建需要的组件

ng g component home
ng g component news
ng g component newscontent

  1. 找到 app-routing.module.ts 配置路由

引入组件

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' } 
];
  1. 找到 app.component.html 根组件模板,配置 router-outlet 显示动态加载的路由
<h1>
	<a routerLink="/home">首页</a> 
	<a routerLink="/news">新闻</a> 
</h1> 
<router-outlet></router-outlet>

二、Angular routerLink 跳转页面默认路由

<a routerLink="/home">首页</a>
<a routerLink="/news">新闻</a>

//匹配不到路由的时候加载的组件 或者跳转的路由

{ 
	path: '**', /*任意的路由*/ 
	// component:HomeComponent 
	redirectTo:'home' 
}

三、Angular routerLinkActive 设 置 routerLink 默认选中路由

<h1>
	<a routerLink="/home" routerLinkActive="active">首页</a> 
	<a routerLink="/news" routerLinkActive="active">新闻</a> 
</h1> 
<h1>
	<a [routerLink]="[ '/home' ]" routerLinkActive="active">首页</a> 
	<a [routerLink]="[ '/news' ]" routerLinkActive="active">新闻</a> 
</h1>
.active{ color:red; }

四、动态路由

  1. 配置动态路由
const routes: Routes = [ 
	{path: 'home', component: HomeComponent}, 
	{path: 'news', component: NewsComponent}, 
	{path: 'newscontent/:id', component: NewscontentComponent}, 
	{ path: '', redirectTo: '/home', pathMatch: 'full' } 
];
  1. 跳转传值
<a [routerLink]="[ '/newscontent/',aid]">跳转到详情</a> 
<a routerLink="/newscontent/{{aid}}">跳转到详情</a>
  1. 获取动态路由的值

import { ActivatedRoute} from '@angular/router';

constructor( private route: ActivatedRoute) { }

ngOnInit() { 
	console.log(this.route.params);
	this.route.params.subscribe(data=>this.id=data.id);
}

五、动态路由的 js 跳转

  1. 引入

import { Router } from '@angular/router';

  1. 初始化
export class HomeComponent implements OnInit { 
	constructor(private router: Router) { } 
	ngOnInit() { }
	goNews(){ 
		// this.router.navigate(['/news', hero.id]); 
		this.router.navigate(['/news']); 
	} 
}
  1. 路由跳转

this.router.navigate(['/news', hero.id]);

六、路由 get 传值 js 跳转

  1. 引入 NavigationExtras

import { Router ,NavigationExtras} from ‘@angular/router’;

2.定义一个 goNewsContent 方法执行跳转,用 NavigationExtras 配置传参。

goNewsContent(){ 
	let navigationExtras: NavigationExtras = { 
		queryParams: { 'session_id': '123' }, 
		fragment: 'anchor' 
	};
	this.router.navigate(['/news'],navigationExtras); 
}

3.获取 get 传值

constructor(private route: ActivatedRoute) { 
	console.log(this.route.queryParams); 
}

七、父子路由

  1. 创建组件引入组件

import { NewsaddComponent } from './components/newsadd/newsadd.component';
import { NewslistComponent } from './components/newslist/newslist.component';

  1. 配置路由
{ 
	path: 'news', 
	component:NewsComponent, 
	children: [ 
		{ path:'newslist', component:NewslistComponent },
		{path:'newsadd', component:NewsaddComponent } 
	] 
}
  1. 父组件中定义 router-outlet

<router-outlet></router-outlet>



自定义模块以及配置路由实现模、 块懒加载

常用模块

NgModule				导入自				为何使用

BrowserModule		@angular/platform-browser	当你想要在浏览器中运行应用时

CommonModule		@angular/common		当你想要使用 NgIf 和 NgFor 时

FormsModule			@angular/forms		当要构建模板驱动表单时(它包含 NgModel )

ReactiveFormsModule	 @angular/forms		当要构建响应式表单时

RouterModule		@angular/router		要使用路由功能,并且你要用到 RouterLink,.forRoot().forChild() 时

HttpClientModule		@angular/common/http		当你要和服务器对话时

创建模块:

ng g module module/user --routing 
ng g module module/article --routing 
ng g module module/product --routing

创建组件:

ng g component module/user
ng g component module/user/components/profile 
ng g component module/user/components/order

ng g component module/article 
ng g component module/article/components/articlelist 
ng g component module/article/components/info

ng g component module/product 
ng g component module/product/components/plist 
ng g component module/product/components/pinfo

配置懒加载
使用 == loadchildren== 代替 component 进行配置

import { HomeComponent } from './components/home/home.component'; 
const routes: Routes = [ 
	{ path:'', component: HomeComponent },
	{ path:'user', loadChildren : './usermodule/usermodule.module#UsermoduleModule' } 
];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值