文章目录
一张图说明Angular程序架构
Angular开发环境搭建
1.安装nodeJs,安装完成后即可使用npm命令
2.全局安装Angular-cli
install -g @angular/cli
安装完成后可以使用ng -v
指令查看安装成不成功
3.使用命令行创建项目
ng new aution // aution是要创建项目的项目名称
项目文件夹和各部分关系
引入npm命令安装的外部模板
当使用npm命令安装完模板后,在angular.json文件中引入,如下图中引入已经安装好的jquery和bootstrap
但此时仍然不能在.ts后缀的模板文件中使用jquery,因为jquery是js写的,TypeScript是不能直接使用,所以还需要安装jquery和boostrap的TS类型描述文件,使用以下指令
npm install @types/jquery
npm install @types/bootstrap
使用指令生成组件
ng g component product // 其中的product是要生成的组件名
启动项目指令
npm run start
数据绑定
将数据绑定在html属性中用[属性]="变量"
的方式绑定,而在vue中用:属性=变量
的方式,注意区分
/* .component.ts文件中 */
export class ProductComponent implements OnInit {
private imgUrl = "http://placehold.it/320x150" // 声明一个私有变量
constructor() { }
ngOnInit() {
}
}
/* .component.html文件中 */
<img [src]="imgUrl" alt="" srcset="" class="img"> //将imgUrl绑定到src属性中
将css类绑定到html标签上
/* 下面的span标签中,已经有了一个class,再将"bindClass"绑定到该标签上,
注意在前面加上“class.” */
/* flag是在.component.ts文件中声明的标志变量(boolean类型),
若flag为true,则绑定“bindClass” 在该标签上*/
<span class="default" [class.bindClass]="flag"></span>
父组件向子组件传数据
/* 父组件中的.component.ts中 */
export class FatherComponent implements OnInit {
private fatherData:number = 15; // 父组件要传递给子组件的数据
constructor() { }
ngOnInit() {
}
/* 父组件中的.html文件 */
<div>
/* 将父组件中的数据“fatherData”传给子组件的变量“childrenData” */
<children-component [fatherData]="childrenData"></children-component> //子组件占位符
<div>
/* 子组件中的.component.ts中 */
export class ChildrenComponent implements OnInit {
@Input() // 必须要有这个@Input()修饰器才能接收父组件的数据
private childrenData:number = 0; // 默认为0,若父组件传递过来数组,则会相应改变
constructor() { }
ngOnInit() {
}
使用Angular Route导航
各个路由对象与Angular各板块间的关系:
在app-routing.moudule.ts文件中配置组件的路由路径:
router的占位符(路由插座)
根路由、子路由的配置
在app-routing.module.ts
文件中可以设置路由,这个文件就像vue项目中router文件夹下的index.js文件,作用都是配置路由。而在给文件的下面配置中,所有没有声明children属性的都是根路由,根路由的显示组件位置是文件app.component.html
中的占位符位置(<router-outlet></router-outlet>
),子路由显示组件的位置在该父路由组件中的html文件中的(<router-outlet></router-outlet>
)
/* 引入组件 */
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ProductComponent } from './product/product.component';
/* 设置路由 */
const routes: Routes = [
{ path: '', component: HomeComponent }, // 没有children字段,是跟路由
{ path: 'product', component: ProductComponent}, // 没有children字段,是跟路由
{ // 这还是跟路由
path:'/test',
component: HomeComponent,
children:[
{ // 这里才是子路由
path: '/childrenTest',
component: ProductComponent
}
]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
路由的在html文件中的使用
使用routerLink
属性将页面导航到所需组件
路由配置文件app-routing.module.ts
根据上一段代码
/* 在app.component.html中 */
<a [routerLink]="['/']">主页</a>
<a [routerLink]="['/product']">主页</a>
<router-outlet></router-outlet> /* 根路由中组件显示的位置 */
/* 在home.component.html中 */
<router-outlet></router-outlet> /* 子路由组件显示的位置 */
在TS文件中用代码导航
1.先在.component.ts
文件中的构造器constructor
中声明路由对象
2.在需要导航的方法中调用路由对象的naigate
方法
constructor(private router:Router) {
}
routerFunction() {
this.router.navigate(['/product']) // 导航到‘/product’路由模块
}
在路由时传递参数
在查询参数中传递数据
<a [routerLink]="['/product']" ['queryParams']="{id: 1}">主页</a>
/* 当点击该链接时就会传递一个id=1的参数到‘/product’ 页面,链接的url显示为"...(前缀)/product?id=1"*/
在.component.ts文件中接收该参数
1.先在构造器中初始化ActivatedRouter
对象
2.在方法中使用ActivatedRouter
对象的snapshop
(参数快照)
private productId:number;
constructor(private routeInfo:ActivatedRouter){
}
getRouterParams() {
this.productId = this.routerInfo.snapshot.queryParams["id"]
}
在路由(url)路径中传递数据
1.在路由配置文件app-routing.module.ts
中修改路由路径配置,让其可以接受参数
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'product/:id', component: ProductComponent} // 修改配置使其可以接收参数
]
2.在组件路由路径中的数据,使其携带参数
<a [routerLink]="['/product', 1]">主页</a>
/* 传递了一个参数1过去,自动会将"product/:id" 中的id填充为1 */
/* url会变为“...(前缀)/product/1” */
在.component.ts文件中接收该参数
private productId:number;
constructor(private routeInfo:ActivatedRouter){
}
getRouterParams() {
this.productId = this.routerInfo.snapshot.params["id"] // 与上一种传参方式的取参方法区别只是将“queryParams”改为“params”
/* 页面的url显示为"...(前缀)/product/1"*/
}
在路由配置中传递数据
路由对象中的snapshop
(参数快照)与subscribe
(参数订阅)
当在不同的链接给同一个组件传递不同的参数,而且该参数都是在组件中的ngOnInit()
方法中取用时,因为在组件初始化时,ngOnInit()
方法只会调用一次(假设该组件与链接在同一个页面展示),这会导致后一次点击链接到该组件的链接中传递的参数取不到。例如:
/* 在a.html页面中,链接到product组件,传递参数1过去 */
<a [routerLink]="['/product', 1]">第一次点击</a>
/* 在b.html页面中,链接到product组件,传递参数2过去 */
<a [routerLink]="['/product', 2]">第二次点击</a>
在product组件中的product.component.ts
文件中
private productId:number;
constructor(private routeInfo:ActivatedRouter){
}
ngOnInit() {
this.productId = this.routerInfo.snapshot.params["id"]
/* 页面的url显示为"...(前缀)/product/1" */
}
当点击上面链接中的“第一次点击”时,组件product被初始化,ngOnInit()
方法被调用一次,productId
被赋值为1,此时的页面url为...(前缀)/product/1
,当再点击“第二次点击”时,组件已经被初始化,不会再调用ngOnInit()
方法,所以productId
仍旧是1,但页面的url变为...(前缀)/product/2
解决办法:使用参数订阅subscribe
ngOnInit() {
this.routeInfo.params.subscribe((params: Params) => this.productId = params["id"])
/* 页面的url显示为"...(前缀)/product/1" */
/* Params类在router包中,注意使用 import { Params } from '@angular/router' 引入*/
}
路由重定向
路由重定向情景:
在路由的配置中没有配置浏览器输入的URL时,将链接地址改为已配置好的路由链接中,如:
const routes: Routes = [
{path: 'home', component: Home}
{path:"product/:id", componnent: ProductComponent}
]
当希望用户在地址栏输入地址,如localhost
时,希望导航到项目的home页面。因为没有配置path为空的路由({path: '', component: Home}
),项目会识别为页面不存在,此时就要使用重定向
const routes: Routes = [
{path: '', redirectTo: '/home', pathMatch: 'full'}, // 当路由为空时,重定向到“/home”路由
{path: 'home', component: Home},
{path:"product/:id", componnent: ProductComponent}
]
辅助路由
使用情景:当主路由的插座(<router-outlet></router-outlet>
)被占用时,还希望多一个插座被其他组件使用,而且不管主路由的插座是否被占用,辅助路由都可以使用
<router-outlet name="aux"></router-outlet> // 辅助路由的插座
const routes: Routes = [
{ path: 'chat', component: ChatComponent, outlet: 'aux' }, // outlet字段说明使用的是辅助路由的插座
]
使用辅助插座的链接书写方式
<a [routerLink]="[{outlets: {aux: 'chat'}}]">开始聊天</a> /* 点击则会连接到辅助插座中的‘chat’路由 */
<a [routerLink]="[{outlets: {aux: null }}]" class="left">结束聊天</a> /* 点击则会辅助插座中的‘null’路由 */
结语
为避免过长,学习笔记1结束,感谢 up主 梅花清幽独立春寒 在哔哩哔哩提供的学习视频