angular
简介
中文官网参考:https://angular.cn/
Angular是谷歌开发的一款开源的web前端框架,诞生于2009年,由Misko Hevery 等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。。
Angular基于TypeScript和react、vue相比 Angular更适合中大型企业级项目。
环境搭建
nodejs安装
1.nodejs安装(前提)
下载安装:http://nodejs.cn/download/
node -v 显示安装的nodejs版本
npm -v 显示安装的npm版本
2.更换npm源为淘宝镜像
npm config get registry #查看 npm config set registry https://registry.npm.taobao.org/
3.typescript安装
npm install typescript -g
4.讲ts文件编译成js
新建一个ts文件
编译
tsc first.ts
使用node运行js
node first.js
这样需要先编译后运行,效率比较慢,可以直接使用如下命令编译和运行一起
注意:需要安装ts-node
npm install -g ts-node
ts-node first.ts
我们使用vscode
5.vscode安装(包括插件安装)
6.vscode终端中运行命令报错解决,参考:https://www.cnblogs.com/annong/p/14931332.html
管理员权限打开PowerShell输入
set-ExecutionPolicy RemoteSigned
然后重启vscode
7.在vscode终端中输入
tsc --init
我们可以看到多了一个文件tsconfig.json
angular安装
1.使用npm 命令安装 angular/cli(全局安装,只需要安装一次)
npm install -g @angular/cli
相关命令
ng version
ng help
Commands: ng add <collection> Adds support for an external library to your project. ng analytics Configures the gathering of Angular CLI usage metrics. See https://angular.io/cli/usage-analytics-gathering ng build [project] Compiles an Angular application or library into an output directory named dist/ at the given output path. [aliases: b] ng cache Configure persistent disk cache and retrieve cache statistics. ng completion Set up Angular CLI autocompletion for your terminal. ng config [json-path] [value] Retrieves or sets Angular configuration values in the angular.json file for the workspace. ng deploy [project] Invokes the deploy builder for a specified project or for the default project in the workspace. ng doc <keyword> Opens the official Angular documentation (angular.io) in a browser, and searches for a given keyword. [aliases: d] ng e2e [project] Builds and serves an Angular application, then runs end-to-end tests. [aliases: e] ng extract-i18n [project] Extracts i18n messages from source code. ng generate Generates and/or modifies files based on a schematic. [aliases: g] ng lint [project] Runs linting tools on Angular application code in a given project folder. ng new [name] Creates a new Angular workspace. [aliases: n] ng run <target> Runs an Architect target with an optional custom builder configuration defined in your project. ng serve [project] Builds and serves your application, rebuilding on file changes. [aliases: s] ng test [project] Runs unit tests in a project. [aliases: t] ng update [packages..] Updates your workspace and its dependencies. See https://update.angular.io/. ng version Outputs Angular CLI version.
2.创建angular项目
ng new firstDemo
3.运行项目,注意必须要先定位到当前项目文件夹内
ng serve --open
4.使用vscode打开项目文件夹
5.创建自己的组件
ng generate component <component-name>
ng g c components/news
模块NgModule
介绍
NgModule 是一个带有 @NgModule 装饰器的类。
Angular 模块把组件、服务、指令和管道打包成内聚的功能块,每个模块聚焦于一个特性区域、业务领域、工作流或通用工具。
NgModule 的元数据会做这些:
- 声明某些组件、指令和管道属于这个模块。
- 公开其中的部分组件、指令和管道,以便其它模块中的组件模板中可以使用它们。
- 导入其它带有组件、指令和管道的模块,这些模块中的元件都是本模块所需的。
- 提供一些供应用中的其它组件使用的服务。
常用模块
模块分类
1.文件模块:框架代码以模块形式组织
内置模块
2.应用模块:功能单元以模块形式组件
自定义模块
当我们项目比较小的时候可以不用自定义模块。但是当我们项目非常庞大的时候把所有的组件都挂载到根模块里面不是特别合适。所以这个时候我们就可以自定义模块来组织我们的项目。并且通过 Angular自定义模块可以实现路由的懒加载。
新建模块命令:
ng g module module/user
//如果需要创建带路由的模块,执行如下命令ng g module module/product --routing
在user模块下面新建一个根组件
ng g component module/user
在 user 模块下新建 address,order,profile 组件
ng g component module/user/components/address ng g component module/user/components/order ng g component module/user/components/profile
自定义模块挂载
如何在根模块挂载 自定义的user 模块呢?
1.在 app.module.ts 引入自己创建的user模块
2.user 模块的根模块中要暴露出 需要被外界访问到的组件
3.在根模板 app.component.html 里引入
注意:如果需要在根组件里直接 使用 app-address 组件,也是需要先在 user 模块 user.module.ts 暴露
自定义模块内创建服务
1.创建
ng g service module/user/services/common
组件Components
介绍
组件是构成应用的砖块。组件包括三个部分:带有 @Component()
装饰器的 TypeScript 类、HTML 模板和样式文件。@Component()
装饰器会指定如下 Angular 专属信息:
-
一个 CSS 选择器,用于定义如何在模板中使用组件。模板中与此选择器匹配的 HTML 元素将成为该组件的实例。
-
一个 HTML 模板,用于指示 Angular 如何渲染此组件
-
一组可选的 CSS 样式,用于定义模板中 HTML 元素的外观
生命周期钩子
参考:https://angular.cn/guide/lifecycle-hooks
当 Angular 实例化组件类并渲染组件视图及其子视图时,组件实例的生命周期就开始了。生命周期一直伴随着变更检测,Angular 会检查数据绑定属性何时发生变化,并按需更新视图和组件实例。当 Angular 销毁组件实例并从 DOM 中移除它渲染的模板时,生命周期就结束了。当 Angular 在执行过程中创建、更新和销毁实例时,指令就有了类似的生命周期。
你的应用可以使用生命周期钩子方法来触发组件或指令生命周期中的关键事件,以初始化新实例,需要时启动变更检测,在变更检测过程中响应更新,并在删除实例之前进行清理。
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-lifecycle', templateUrl: './lifecycle.component.html', styleUrls: ['./lifecycle.component.css'] }) export class LifecycleComponent implements OnInit { title:string='' age:number=0 constructor() { console.log('构造函数constructor:对变量初始化') } ngOnChanges(): void { console.log('ngOnChanges:子组件绑定的属性值发生变化时调用') } ngOnInit(): void { console.log('ngOnInit:用来向后台请求数据,只执行一次') } ngDoCheck(): void { console.log('ngDoCheck:') } ngAfterContentInit(): void { console.log('ngAfterContentInit:') } ngAfterContentChecked(): void { console.log('ngAfterContentChecked:') } ngAfterViewInit(): void { console.log('ngAfterViewInit:当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用,只执行一次') } ngAfterViewChecked(): void { console.log('ngAfterViewChecked:') } ngOnDestroy(): void { console.log('ngOnDestroy:Angular 销毁指令或组件之前立即调用') } setTitle():void{ this.title='title change' } }
组件交互
父组件将值传递给子组件
1.在子组件中导入Input模块
import { Component, OnInit,Input } from '@angular/core';
2.在子组件中定义要从父组件中接收的变量
@Input() product!:Product
@Input() title:string=''
3.在父组件中定义变量数据
4.在父组件的view中绑定数据
<app-hero-child [product]="product"></app-hero-child>
父组件将方法传递给子组件
1.在父组件中定义一个方法
doParent(){ alert('这是父组件的方法') }
2.在父组件的html中传递方法
<app-hero-child [product]="product" [doParent]="doParent"></app-hero-child>
3.在子组件中导入Input模块
import { Component, OnInit,Input } from '@angular/core';
4.在子组件中定义要从父组件中接收的方法变量
@Input() doParent:any
5.在子组件中定义一个方法调用父方法变量
注意:父方法变量不能和子组件中的方法重名
doParentMethord():void{ this.doParent() }
在父组件中获取子组件的数据和方法 @ViewChild()
1.父组件中加#childItem
<app-hero-child #childItem [product]="product" [doParent]="doParent" (showTitle)="showTitle($event)"></app-hero-child>
2.父组件中接收
@ViewChild("childItem")
childItem!:HeroChildComponent
3.子组件定义数据和方法
calc(a:number,b:number):number{ return a+b; }
4.父组件调用
calc():void{ let result = this.childItem.calc(3, 4); alert(result) }
模板
绑定
文本插值
{{}}是模板表达式
使用{{ }}
说明:但组件中定义的数据发生改变时会自动刷新模板中的值
Attribute绑定
注意:attribute绑定的是标签本身自有的属性或者自己定义的属性
Attribute 绑定语法类似于 Property 绑定,但不是直接在方括号之间放置元素的 Property,而是在 Attribute 名称前面加上前缀 attr,后跟一个点 .。然后,使用解析为字符串的表达式设置 Attribute 值。
<p [attr.attribute-you-are-targeting]="expression"></p>
Property 绑定
注意:property绑定的是标签在javascript中具有的属性,
ps:
<a [attr.myattr]="title" [attr.href]="url" [href]="url">超链接</a>
生成如下:
<a _ngcontent-fxg-c49="" href="http://www.baidu.com" myattr="标题">超链接</a>
结论:myattr是我们自定义的attribute,href既是a标签本身的attribute,也是a标签在JavaScript中的属性(document.getElementsByName("a").href)
管道
使用管道来转换字符串、货币金额、日期和其他数据以进行显示。
管道是在模板表达式中使用的简单函数,用于接受输入值并返回转换后的值。管道很有用
模板引用变量
在模板中,要使用井号 #
来声明一个模板变量。下列模板变量 #phone
声明了一个名为 phone
的变量,其值为此 <input>
元素。
<input #phone placeholder="phone number" />
可以在组件模板中的任何地方引用某个模板变量。这里的 <button>
就引用了 phone
变量。
<button type="button" (click)="callPhone(phone.value)">Call</button>
指令
指令是为 Angular 应用程序中的元素添加额外行为的类。使用 Angular 的内置指令,你可以管理表单、列表、样式以及要让用户看到的任何内容。
内置属性型指令
ngClass
<div [ngClass]="{'class1':true,'class2':false }" >ngclass</div>
ngStyle
<div [ngStyle]="{'color':'red','font-size':'22px'}">ngstyle</div>
ngModel
内置结构型指令
ngIf
NgIf 指令应用于宿主元素来添加或删除元素。
<span *ngIf="isFlag">我是flag</span> <button (click)="changeFlag()">隐藏显示flag</button>
ngFor
<ul> <li *ngFor="let item of colors;let index=index">{{item}}</li> </ul>
NgSwitch
<h3>switch</h3>
<ul [ngSwitch]="switch">
<li ngSwitch="1">我是主要的</li>
<li ngSwitch="2">我是次要的</li>
</ul>
自定义指令
自定义属性指令,可以额外的给标签元素增加属性、事件、处理输入值
1.创建
ng generate directive directive/highlight
<div appHighlight >使用自定义指令</div>
也可以定义id、类选择器指令
3.处理用户事件
依赖注入&服务
1.创建服务
ng g service services/product
2.在组件中引入服务模块,然后通过构造器依赖注入
注意:构造器中的变量必须要带private或者public
表单
在app.modules.ts中要引入ReactiveFormsModule模块
然后还要导入模块
响应式表单
FormControl
1.在组件中导入表单控件
import { FormControl } from '@angular/forms';
2.在组件中创建一个FormControl实例
myForm=new FormControl('ddd');
3.在模板中注册这个FormControl
<input [formControl]="myForm" >
FormGroup
讲多个formControl放到一个组内
1.导入FromGroup模块
import { FormControl,FormGroup } from '@angular/forms';
2.实例化一个FromGroup
formGroup=new FormGroup({ name:new FormControl(''), age:new FormControl(), sex:new FormControl })
3.模板中使用
<form [formGroup]="formGroup"> <div> <label>名称</label><input type="text" formControlName="name"> </div> <div> <label>年龄</label><input type="text" formControlName="age"> </div> <div> <label>性别</label> <select formControlName="sex"> <option value="1">男</option> <option value="0">女</option> </select> </div> <button (click)="confirm()" [disabled]="!formGroup.valid">提交</button> </form>
4.组件中接收
模板表单
1.组件中定义变量
2.模板中用ngModel绑定
<input [(ngModel)]="title">{{title}}
动态表单
动态表单是基于响应式表单的,为了让应用访问响应式表达式指令,根模块会从 @angular/forms 库中导入 ReactiveFormsModule。
import { ReactiveFormsModule } from '@angular/forms';
http数据请求
1.在app.modules.ts中引入:
2.把 HttpClient 服务注入成一个应用类的依赖项
创建一个服务config:ng g s services/config
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class ConfigService { constructor(private http:HttpClient) { } }
3.在configService中引入
import { Observable, throwError } from 'rxjs'; import { catchError, retry } from 'rxjs/operators';
4.调用
this.http.get("url", { }).subscribe((response) => { })
路由
路由就是根据不同的url地址,动态的让根组件挂载其它组件来实现一个单页面应用。
定义路由
1.新建项目时选择路由,会自动在根模块导入路由相关依赖,同时会生成一个路由配置文件app-routing.module.ts
2.在app-routing.module.ts中的Routes数组定义你的路由
3.把路由添加到应用中
注意:组件模板要包含 <router-outlet> 标签。该元素会通知 Angular,你可以用所选路由的组件更新应用的视图。
<nav> <a routerLink="home" routerLinkActive="active">主页</a> <a routerLink="news" routerLinkActive="active">新闻</a> <a routerLink="product" routerLinkActive="active">产品</a> </nav> <router-outlet></router-outlet>
路由传值
1.设置要传递到路由组件内部的参数
<a routerLink="news" [queryParams]="{name:'jack'}" routerLinkActive="active">新闻</a>
2.组件导入
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
3.获取值
ngOnInit(): void { this.route.queryParams.subscribe(params => { this.name = params['name']; }); }
嵌套路由
设置页面标题