angular学习分享

Angular7入门总结篇

一、Angular 介绍

  • 根据项目数统计 angular(1.x 、2.x 、4.x、5.x、6.x、7.x)是现在网上使用量最大的框架
  • Angualr 基于 TypeScriptreactvue 相比, Angular 更适合中大型企业级项目。

目前 2018 年 11 月 25 日 angular 最新版本 angular7.x。根据官方介绍,Angular 每过几个月 就会更新一个版本。此教程同样适用于后期更新的 Angular8.xAngular9.x

image

学习 Angular 必备基础

必备基础:htmlcssjses6Typescript

二、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 文件中 @NgModuledeclarations 列表中声明

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 装饰器定义 Pipemetadata 信息,如 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 里面最常用的ObservablefromEvent

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

  • 回调函数
  • 事件监听/发布订阅
  • 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'
} ];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343