Augular笔记

Augular

Google开源的JavaScript的库web前端框架

诞生于2009年

https://angular.cn

软件安装

image-20201010015800664

代码提示:Angular Snippets

中文:Chinese

环境搭建

ndoejs

node.js 稳定版本

node -v

npm -v

cnpm

建议安装一下cnpm

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

cnpm -v

安装 angular/cli 脚手架(只需要安装一次)

npm install -g @angular/cli

或者

cnpm install -g @angular/cli

测试脚手架

ng v

创建项目

打开cmd命令控制窗口,进入文件目录

可以先不安装路由,使用css即可

ng new 项目名称
ng new angulardemo

再次创建项目时,可以跳过安装依赖
ng new angulardemo --skip-install

安装依赖

npm i

或者

cnpm install

运行项目

ng serve --open

介绍

框架结构

image-20200927193808051

app.module.ts

image-20200927193822045

自定义组件

https://cli.angular.io/

组件component

//创建组件,一个home组件
ng g component components/home

//app.module.ts 中加载
//1、引入
//2、加载

//app.component.html 中使用引用组件
<app-home></app-home>

图片资源

.ts 文件中
picUrl='https://xxxxx.png';

.html 文件中
//引用本地资源
<img src="assets/images/01.png" alt="收藏" />

//引用网络资源
<img [src]="picUrl" />

循环判断

for循环

<ol>
    <li *ngFor="let val of items;let key=index;">
    	{{key}} --> {{val}}
    </li>
</ol>
//key 是索引,val是值



if判断

//.ts 文件
flag : boolean = false;

//.html 文件
<div *ngIf="flag">
	<img src="assets/images/01.png" />
</div>
<div *ngIf="!flag">
	<img src="assets/images/01.png" />
</div>

ngSwicth

image-20200927222154191

image-20200927222659436

绑定属性

ngClass

ngClass

//动态改变样式, blue 样式是true        red 样式是false
<div [ngClass]="{'blue':true,'red',false}">
    ngClass演示
</div>

//根据 flag 改变样式
<div [ngClass]="{'orange':flag,'red',!flag}">
    ngClass演示
</div>

ngStyle

ngStyle

//直接设置样式
<p [ngStyle]="{'color':'blue'}">
    我是一个标签
</p>

//使用表达式赋值
attr:string = 'red';
<p [ngStyle]="{'color' : attr}">
    我是一个标签
</p>

管道

在模板里面调用一个方法

大小写转换

大小写转换

<p>{{str | uppercase}}</p>      //转换成大写
<p>{{str | lowercase}}</p>      //转换成小写

日期格式转换(常用)

日期格式转换

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

小数位数

小数位数

//接收的参数格式为 {最少整数位数}.{最少小数位数}-{最多小数位数}
<p>{{ p | number:'1.2-4'}}</p>

JavaScript 对象序列化

JavaScript 对象序列化

<p>{{ {name : 'semlinker'} | json }}</p>
//output:  {"name" : "semlinker"}

slice

slice

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

管道链

管道链

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

自定义管道

自定义管道

使用@Pipe 装饰器定义 Pipe 的 metadata信息,如 Pipe 的名称 - 即 name 属性

实现 PipeTransform 接口中定义的 transform 方法

1.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 WelconePipe')
		}
		return "Welcome to " + value;
	}
}

1.2 WelcomePipe使用

<div> 
    <p ngNonBindablee>{{ 'semlinker' | welcome }} </p>
    <p>{{ 'semlinker' | welcome }} </p>  //output: Welcome to semlinker
</div>

2.1 RepeatPipe 定义

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

[@Pipe](/user/Pipe)({name: 'repeat'})
export class RepeatPipe implements PipeTransform {
	transform(value: any, times: number){
		return value.repeat(times);
	}
}

RepeatPipe使用

<div>
    <p ngNonBindable>{{ 'lo' | repeat:3 }}</p>
    <p>{{ 'lo' | repeat:3 }}</p>
    //output: lololo
</div>

事件

(click)

// .ts
myrun(){
	alert('自定义方法')
}

// .html文件
<button (click)="myrun()" > 执行事件</button>

(keydown)(keyup)

******普通方法******
// .ts
keyDown(){
	console.log('自定义deydown方法');
}

// .html文件
<input type="text" (keydown)="keyDown()" ></input>


******获取对象******
// .ts
keyDown(e){
	console.log('自定义deydown方法' + e.keyCode);
	e.target.value  //获取 input 里面的值
}

// .html文件,传入事件对象
<input type="text" (keydown)="keyDown($event)" ></input>

获取事件对象


runEvent(event){
	var dom:any = event.target;
	dom.style.color="red";
}

<button (click)="runEvent($event)">执行方法获取事件对象</button>

(change)


// 

双向数据绑定(MVVM)

这里只是针对表单

首先:app.module.ts 引入 FormsModule

import { FormsModule } from '@angular/forms';
keywords:string = '这是默认值';

<input type="text" [(ngModel)]='keywords'></input> {{keywords}}

表单

dom操作(angular里不推荐)

image-20200927234446047

双向数据绑定(推荐)

先引入 FormsModule

image-20200927234627240

[(ngModule)]="functionxxxx"

input type="text"

input type="radio"

image-20200927235313141

image-20200927235532395

select

<select name="city" id="city" [(ngModule)]="peopleInfo.city">
    <option [value]="item" *ngFor="let item of peopleInfo.cityList">{{tiem}}</option>
</select>

image-20200928000207905

input type="checkbox"

image-20200928001439770

textarea

image-20200928001640562

完整toDoList

服务

可以提供公共方法

服务和组件 关系说明

组件之间不能相互调用,保持独立

服务之间可以相互调用

组件 -> 服务 ,组件可以调用服务中的方法

服务 -> 组件,服务不能调用组件的东西

使用方法

创建命名

ng g service services/storage

app.modeule.ts 中引入

image-20201011220814612

在使用的组件中引用 服务对象

  • import引入
  • constructor 构造方法中 初始化,也称注入

使用方法,调用服务中的get方法:

let s = this.storage.get()

image-20201011220943175

服务,封装功能

image-20201011221706286

dom操作

方法一:原生 js 操作dom

在 augular 中, ngOnInit() 方法不是 dom 加载完成的方法, 存在 ng 语法的 dom ,会获取不到

image-20201011224522125

实现 原生js 获取dom 要 在 ngAfterViewInit() 方法中

image-20201011224650896

方法二:ViewChild 操作 dom

  1. 模板中给dom起一个名字

    <div #myBox>
        我是一个dom节点
    </div>
    
  2. 在业务逻辑里面引入 ViewChild

    import { Component, OnInit, ViewChild} form '@angular/core';
    
  3. 通过viewchild获取dom节点

    这个要卸载类里面

    @ViewChild('myBox') myBox:any;
    
  4. 在生命周期函数 ngAfterViewInit() 中获取到

    this.myBox.nativeElement
    
    
    

ViewChild 另一个作用,父组件调用子组件

使用方法如同 viewchild 操作 dom 方法一样

执行 CSS3 动画

null。。。

父子组件、组件之间的通信

父组件 给 子组件传值(@input)

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

子组件可以 获取父组件的数据、执行父组件的方法

父 -> 子,传数据

父 -> 子,传数据

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

    <app-header [msg]="msg"></app-header>
    
  2. 子组件引入 input 模块

    import { Component, OnInit, Input} form '@angular/core';
    
  3. 子组件中 @input 接收父组件传过来的数据

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

父 -> 子,传方法

父 -> 子,传方法

和传数据差不多

父 -> 子,传父组件

父 -> 子,传 整个父组件

在标签上 直接传入 this

image-20201011234259252

子组件 给 父组件传值

方法一:父组件 通过 @viewchild 主动获取子组件

父组件可以 获取子组件的数据、执行子组件的方法

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

    image-20201011235641100

  2. 引入 viewchild

  3. 3

  4. 父组件接收到数据会调用自己的 runParent 方法,这个时候就能拿到子组件 的数据

    image-20201011235807154

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

  1. 子组件引入 Output 和 EventEmitter

image-20201011235946217

  1. 子组件中实例化 EventEmitter

    image-20201012000005131

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

    image-20201011235919192

  3. 父组件调用子组件的时候,定义接收事件 outer 就是子组件的 eventfmitter对象outer

    image-20201012000939893

  4. 父组件 监听 outer ,会触发 父组件自己的 run 方法

非父子组件:

方法一:LocalStorage

方法二:通过 服务

生命周期函数

8个 函数

image-20201012001944444

image-20201012002115054

Rxjs 介绍

参考手册: https://www.npmjs.com/package/rxjs

中文手册: https://cn.rx.js.org/

RxJS 是 ReactiveX 编程理念的 JavaScript版本。ReactiveX 来自微软,它是一种针对异步数据流的编程。简单来说,它将一切数据,包括HTTP请求,DOM事件或者普通数据等包装成流的形式,然后用强大丰富的操作符对流进行处理,使你能以同步编程的方式处理异步数据,并组合不同的操作符来轻松优雅的实现功能。

常见异步编程的几种方法

回调函数

1、回调函数

  • 外部调用
//传入回调函数 data,获得request服务中 getCallbackData 方法
this.request.getCallbackData((data)=>{
    console.log(data)
})
  • 实现
//服务中,实现getCallbackData方法
getCallbackData(cb){

    setTimeout(()=>{
        var username='张三';
        //返回 username
        cb(username);
    //延时 1秒执行 setTimeout 里面的内容
    }, 1000)
}

事件监听、发布订阅

2、事件监听、发布订阅

promise 获取异步数据

3、promise 获取异步数据

se6 规范提供promise方法,获取异步信息

  • 外部调用
//调用 request 服务中的getPromiseData方法
var promiseData=this.request.getPromiseData();
//promise 提供的 then 关键字
promiseData.then((data)=>{
	console.log(data);   
})
  • 实现
getPromiseData(){
    
    //成功返回resolve,失败返回reject。也可以不写 reject
    return new Promise((resolve,reject)=>{
        
        setTimeout(()=>{
            var username='张三';
            resolve(username);
        },1000)
    })
}

Rxjs 获取异步数据

4、Rxjs 获取异步数据,第三方模块

  • 准备

    首先需要引入模块

    import { Observable } from 'rxjs';

  • 外部调用

//调用 request 服务中的 getRxjsData 方法
var rxjsData = request.getRxjsData();
rxjsData.subscribe((data)=>{
    console.log(data); 
})

//形式2:调用
stream.subscribe(value=>console.log(value));
  • 实现
//引入
import { Observable } from 'rxjs';

getRxjsData(){
    return new Observable(observable=>{
        setTimeout(()=>{
            //成功用 next
            observable.next('observable timeout');
            //失败用 error
            observable.error('数据')
        },1000);
	})
}

//形式2:也可以这样接收 observable 的值
let stream = new Observable(observable=>{
    setTimeout(()=>{
        observable.next('observable timeout');
    },1000);
});
return stream;

Rxjs相比promise有诸多优点

  1. 动作可以通过 unsubscribe() 方法中途撤回
  2. 发射多个值
  3. Rxjs提供了多种工具函数
  4. 等等......

setTimeout,延时执行。

setInterval,定时器。

Rxjs定时多次执行

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

stream.subscribe(value=>console.log("TTTTT"+value));

Rxjs6.x 以上使用方法

filter:过滤筛选

map:对数据进行处理

var streamNum=this.request.getRxjsIntervalNum();

//在 pipe 管道中进行处理
streamNum.pipe(
	filter((value)=>{
        if(value%2==0){
            return true;
        }
    }),
    map((value)=>{
        return value*value;
    })
)

.subscribe((data)=>{
    console.log(data);
})

数据交互

angular 5.x 以后 get、post 和服务器交互使用的是 HttpCilentModule 模块

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

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

imports: [
    BrowserModule,
    HttpCilentModele
]

get 请求数据

//在用到的地方引入 HttpCilent 并在构造函数声明
import { HttpCilent } from "@angular/common/http";

constructor(public http:HttpCilent){ }

//使用
var api = "http://a.itying.com/api/productlist"

this.http.get(api).subscribe(response => {
    console.log(response);
})

post 提交数据

//在用到的地方引入 HttpCilent、HttpHeaders 并在构造函数声明 HttpCilent
import { HttpCilent,HttpHeaders } from "@angular/common/http";

constructor(public http:HttpCilent){ }

//使用
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);
})

jsonp 请求数据

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

import { HttpCilentModule,HttpCilentJsonpModule } from '@angular/common/http';

imports: [
    BrowserModule,
    HttpCilentModele,
    HttpCilentJsonpModule
]

//在用到的地方引入 HttpCilent 并在构造函数声明 HttpCilent
import { HttpCilent } from "@angular/common/http";
constructor(public http:HttpCilent){ }

// 使用 jsonp 请求数据
const httpOptions = {
    headers: new HttpHeaders({'Content-Type':'application/json'})
};

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

使用 第三方模块 axios 请求数据

1、安装 axios 模块

npm install axios --save

2、引入

import axios from 'axios';

3、使用

//可以先封装,也可以直接使用 axios.get 直接获取
axiosGet(api){
    //使用 Promise 封装,也可以使用其他方法
    return new Promise((resolve,reject) => {
        
        axios.get(api)
        .then(function (response){
            console.log(response)
        })
        
    })

}


//调用封装的方法
getAxiosData(){
    console.log('axios 获取数据');
    let api="http://a.itying.com/api/productlist";
    
    this.httpService.axiosGet(api).then((data)=>{
        console.log(data)
    })
}

路由

以前组件之间挂载,是靠手动在一个组件中挂载其他组件的。

路由就是根据 不同的 url 地址,动态的让根组件挂载其他组件

来实现一个单页面应用

使用路由

1、创建路由项目

选择yes, 创建带路由的项目

ng new angulardome --skip-install

image-20201013233608634

2、创建组件

创建需要的组件,在 app 中注入

3、配置路由

把组件 加入 路由配置

4、前端页面调用

找到 app.component.html 根组件模板,配置 router-outlet 显示动态加载的路由

image-20201013233921494

动态路由

//这种写法 是 动态路由
<a [routerLink]="[ '/home' ]"> 首页 </a>

//这种写法 是 静态路由
<a routerLink='/home'> 首页 </a>

默认挂载的组件 ,在路由配置中

{ 
    path: '**' , redirectTO 'home'
}

选择路由后,保持选择 状态

使用 routerLinkActive="active" ,active 名 可以随意写。

<a [routerLink]="[ '/home' ]" routerLinkActive="active"> 首页 </a>

跳转

动态路由的 js 跳转
路由 get 传值 js 跳转

父子路由

原文地址:https://www.cnblogs.com/kutsu/p/13742684.html