Angular_study

一、Angular创建项目

0、准备工作

使用npm命令安装angular/cli
npm uninstall -g  @angular/cli //删除旧版本
cnpm install -g @angular/cli //安装
cnpm install -g @angular/cli@7.0.6 //指定安装版本
验证angular/cli
ng v

1、打开命令行进入你要创建项目的目录

2、创建项目

ng new 【项目名】

①直接安装
ng new demo1
②跳过npm i安装
ng new demo1 --skip-install

3、安装依赖

cnpm install

4、运行项目

ng serve --open

二、Angular介绍

1、目录结构分析

  • e2e //端到端测试
  • ng new demo1 //安装的第三方模块
  • src //项目的所有文件都在里面
    • app //组件,以及app.module.ts定义根模块
    • assets //静态资源
    • enviroments//包含为各个目标环境准备的文件
      • favicon.ico
      • index.html // 主页面
      • main.ts //应用的主要入口
      • polyfills.ts // 填充库能帮我们把这些不同点进行标准化
      • style.css //全局样式
      • test.ts //单元测试的主要入口点
    • package.json //npm配置文件

2、创建使用组件

ng g component components/head

三、Angular组件以及组件中的模板合成完整

1、定义数据

声明属性的几种方式:

public 共有(默认) 可以在这个类里面使用,也可以在类外面使用
protect 保护类型 只有在当前类里和他的子类里可以使用
private 私有 只有在当前类里才能使用
//定义普通数据
public title = "我是新闻组件";
msg = "我是新闻组件";
username:string = "张三";
public student:any = 1223131; //(推荐)
public userInfo:object = {
    username : "张三"
    age : '20'
} 
public content = "<h2>我是一个html标签</h2>";

//定义数组
public arr = ['1','2','3'];
public list:any[] = ['1',2,'3']; //推荐
public items:Array<number> = [1,2,3];

public userlist:any[] = [
    {
        name:'张三'
        age:20
    },
    {
        name:'李四'
        age:21
    }
    {
        name:'王五'
        age:41
    }
]

public cars:any[] = [
    {
        cate:'宝马',
        list:[
            {
                title:'宝马x1'
                price:'10w'
            },
            {
                title:'宝马x2'
                price:'20w'
            },
            {
                title:'宝马x3'
                price:'30w'
            },
        ]
    },
    {
        cate:'奥迪',
        list:[
            {
                title:'奥迪Q1'
                price:'10w'
            },
            {
                title:'奥迪Q2'
                price:'20w'
            },
            {
                title:'奥迪Q3'
                price:'30w'
            },
        ]
    },
]

2、绑定数据

①angular模板里绑定属性
//静态绑定
<div title = "我是一个div">
    鼠标瞄上去看一下
</div>

//动态绑定
<div [title] = "student">
    张三
</div>
②angular模板里绑定html
<span [innerHTML] = 'content'></span>

3、数据循环

①*ngFor 普通循环
<ul>
    <li *ngFor = "let item of arr">
        {{item}}
    </li>
</ul>

<ul>
    <li *ngFor = "let item of userlist">
        {{item.username}} --- {{item.age}}
    </li>
</ul>

<ul>
    <li *ngFor = "let item of cars">
        <h2>{{item.cate}}</h2>
        <ol>
            <li *ngFor = "let car of item.list">
                {{car.title}} --- {{car.price}}
            </li>
        </ol>
    </li>
</ul>

四、Angular中的服务以及数据持久化

1、创建服务命令

ng g service my-new-service

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

2、引入并配置服务

//①在app.module.ts中引入创建的服务
import { StorageService } from './service/storage.service';

providers: [StorageService], // 在NgMOdule里面的providers里面注入依赖服务

//②在目标模块中引入
import { StorageService } from '../../service/storage.service';

constructor(public storage:StorageService){
    
    console.log(this.storage.get());
}

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

//组件和指令初始化完成,并不是真正的dom加载完成
ngOnInit() {
}

//视图加载完成以后触发的方法  dom加载完成 (建议把dom操作写在这个里面)
ngAfterViewInit():void {
}

1、原生dom操作

2、ViewChild中的dom操作

<div #myattr> </div>
//在业务逻辑里面引入ViewChild
import {Component, ViewChild, ElementRef} from '@angular/core'

@ViewChild('myattr') myattra: ElementRef;

//获取并操作dom节点
ngAfterViewInit():void {
    console.log(this.myattr.nativeElement);
	this.myattr.nativeElement.style.width = '100px';
	this.myattr.nativeElement.style.height = '200px';
}

3、侧边栏动画

<div>
    内容区域
    <button (click) = "showAside()"> 弹出侧边栏 </button>
    <button (click) = "hideAside()"> 隐藏侧边栏 </button>
</div>

<aside id = "aside">这是一个侧边栏</aside>
#aside {
    width: 200px;
    height: 100%;
    right: 0px;
    top: 0px;
    transfrom: translate(100%,0);
    transition: all 2s;
}
showAside(){
    var asideDom:any = document.getElementById('aside');
    asideDom.style.transform = "translate(0,0)";
}

hideAside(){
    var asideDom:any = document.getElementById('aside');
    asideDom.style.transform = "translate(100%,0)";
}

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

父组件给子组件传值

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

子组件给父组件传值

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

非父子组件

  • 组件之间传值
  • 共享方法

1、父组件给子组件传值-@input

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

①父组件调用子组件的时候传入数据/方法

<app-header [msg] = "msg"> </app-header> //传数据
<app-header [run] = "run"> </app-header> //传方法
<app-header [home] = "this"> </app-header> //传整个父组件

②子组件引入Inpu模块

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

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

export class HeaderComponent implements OnInit {
    @Input() msg:string;
    @Input() run:any;
    @Input() home:any;
}

④使用数据/方法

alert(this.msg); //调用数据
this.run(); //调用方法

//调用组件
alert(this.home.msg); //调用数据
this.home.run(); //调用方法

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

①、调用子组件给子组件定义一个名称

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

②、引入ViewChild

@ViewChild('footer') footer:any;

③、调用数据

alert(this.footer.msg);

3、子组件通过@Output触发父组件的办法

①、子组件引入Output和EventEmitter

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

②、子组件中实例化EventEmitter

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

③、子组件通过EventEmitter对象outer实例广播数据

sendParent(){
    this.outer.emit('msg from child')
}

④、父组件调用子组件的时候,定义接收事件,outer就是子组件中的EventEmitter对象outer

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

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

runParent(e){
    console.log(e);  //子组件给父组件广播的数据
}

七、Angular中的生命周期函数

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

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

https://angular.cn/guide/lifecycle-hooks

constructor() //【非生命周期函数】除了使用简单的值对局部变量进行初始化之外,什么都不应该做
ngOnChanges() //当被绑定的输入属性的值发生变化时调用(父子组件传递值的时候会触发)
ngOnInit() //请求数据一般放在这个里面
ngDoCheck() //检测,并在发生Angular无法或者不愿意自己检测的变化时作出反应(写一些自定义的操作)
ngAfterContentInit() //当把内容投影进组件之后调用
ngAfterContentChecked() //每次完成被投影组件内容的变更检测之后调用
ngAfterViewInit() //初始化完组件视图及其子视图之后调用(dom操作放在这个里面)
ngAfterViewChecked() //每次做完组件视图和子视图的变更检测之后调用
ngOnDestroy() //当Angular每次销毁指令/组件之前调用

八、Rxjs异步数据流编程

1、Rxjs处理异步

import { Observable } from 'rxjs';

let stream = new Observable((observer)=> {
    setTimeout(()=> {
        observer.next('timeout');
        //observer.error();
    },2000);
});

stream.subscribe(value => console.log(value));

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

2、Rxjs unsubscribe取消订阅

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

//过一秒之后撤回刚才的操作
var undo = stream.subscribe(value => console.log(value));

setTimeout (()=>{
    undo.unsubscribe(); //取消订阅
},1000)

3、Rxjs 订阅后多次执行

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

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

4、Angular6.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++);
    },2000);
});

stream.pipe(
    filter(val=>{
        if(val%2 == 0){
            return true;
        }
    })
)
.subscribe(value => console.log(value))

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

九、Angular中的数据交互

1、Angualr get请求数据

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

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

imports: [
    BrowserMoudle,
    HttpClientModule
]

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

import { HttpClient } from '@angular/common/http'; //当作一个服务

constructor(public http:HttpClient) {}

③、get请求数据

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

2、Angular post提交数据

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

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

import { HttpClient, HttpHeaders} from '@angular/common/http'; //当作一个服务

constructor(public http:HttpClient) {}

③、post提交数据

const httpOptions = {
    headers: new HttpHeders({'Content-Type':'applications/json'})
};

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

3、Angular Jsonp请求数据

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

①、安装axios

npm install axios --save

②、用到的地方引入axios

import axios from 'axios'

③、看文档使用

十、Angular中的路由

1、普通路由

1、创建一个带路由的项目

2、创建需要的组件

3、引入组件

4、配置路由

const routes: Routes  = [
    {	path: 'home', component: HomeCompoent},
    {	path: 'newscontent/:id', component: NewsContentCompoent},
    {
        path: '',
     	redirectTo:'home',
     	pathMatch: 'full'
    },
    //匹配不到路由的时候加载的组件或者跳转的路由
    {
        path: '**',
        redirectTo:'home',
    }
];

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

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

<router-outlet> </router-outlet>

2、动态路由的js跳转

①、引入

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

②、初始化

export class HomeComponent implements OnInit {    
    constructor(private router: Router){
        
    }
}

③、使用

this.router.navigate(['/newscontent/','1243'])

3、路由get传值js跳转

①、引入NavigationExtras

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

②、定义一个goNewsContent方法执行跳转,用NavigationExtras配置传参

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

4、父子路由


front-end

803 Words

22227-722-12 15:00 +0800