路由
子路由
路径参数
路径对象参数
查询参数
页面传值
GET传值:
<!-- 常规 -->
<a href="/info?id=123">详情123</a>
<!-- Angular GET传值
-->
<a [routerLink]="['/info']" [queryParams]="{id:key}">详情{{key}}</a>
获取get传值的id值:
this.route.queryParams.subscribe((date)=>{
console.log(date);
})
动态路由:
<a [routerLink]="['info', key]">详情{{key}}</a>
获取动态路由的值:
this.route.params.subscribe((data)=>{
console.log(date);
})
js页面跳转
动态路由的js跳转:
// 1. 构造函数注入@angular/router:Router
// 2. 跳转:
this.router.navigate(['/info', '123'])
get传值的js跳转:
// 1. 构造函数注入@angular/router:Router + @angular/router:NavigationExtras
// 2. 跳转:
let navigationExtras: NavigationExtras = {
// 传递两个参数的情况
queryParams: {'seesion_id': 123},
fragment: 'onefine'
}
this.router.navigate(['main'], navigationExtras);
管道
内置管道示例:
src\app\app.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'ifine';
obj = {name: 'onefine', age: 18, home: 'km'}
date: Date;
price: number;
data = [1, 2, 3, 4, 5, 6, 7];
constructor() {
this.date = new Date();
this.price = 123456.123;
}
}
src\app\app.component.html:
<p> {{ obj | json }}</p>
<p> {{ date | date: 'MM-dd' }}</p>
<p> {{ price | currency }} </p>
<p> {{ price | currency: 'CNY' }} </p>
<p> {{ data | slice:1:3 }}</p>
另外,加载中文相关资源[可选]:
src\app\app.module.ts:
import { LOCALE_ID, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeModule } from './home';
import { SharedModule } from './shared/shared.module';
import localZh from '@angular/common/locales/zh-Hans';
import { registerLocaleData } from '@angular/common';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
SharedModule,
AppRoutingModule,
HomeModule
],
providers: [
{
provide: LOCALE_ID,
useValue: 'zh-Hans'
}
],
bootstrap: [AppComponent]
})
export class AppModule {
constructor() {
// 注册中文相关数据
registerLocaleData(localZh, 'zh');
}
}
自定义管道示例:
src\app\shared\pipes\ago.pipe.ts:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'appAgo'
})
export class AgoPipe implements PipeTransform {
transform(value: any, ...args: any[]): any {
if (value) {
// 转为时间戳 / 1000
const seconds = Math.floor((+new Date() - +new Date(value)) / 1000);
if (seconds < 30) {
return '刚刚';
}
const intervals = {
年: 3600 * 24 * 365,
月: 3600 * 24 * 30,
周: 3600 * 24 * 7,
天: 3600 * 24,
小时: 3600,
分钟: 60,
秒: 1
};
let counter = 0;
for (const unitName in intervals) {
const unitValue = intervals[unitName as keyof typeof intervals];
counter = Math.floor(seconds / unitValue);
if (counter > 0) {
return `${counter} ${unitName} 前`;
}
}
return value;
}
}
}
src\app\app.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'ifine';
date: Date;
constructor() {
this.date = this.minusDays(new Date(), 2);
}
minusDays(date: Date, days: number): Date {
const result = new Date(date);
result.setDate(result.getDate() - days);
return result;
}
}
src\app\app.component.html:
<p> {{ date | appAgo }}</p>
依赖注入
import { Component, Injectable, Injector, OnInit } from '@angular/core';
// 产品
@Injectable()
class Product {
constructor(private name: string, private clolr: string) {}
}
// 订单
@Injectable()
class PurchaseOrder {
private amount: number = 0;
constructor(private product: Product) { }
}
@Component({
selector: 'app-home-grand',
templateUrl: './home-grand.component.html',
styleUrls: ['./home-grand.component.scss']
})
export class HomeGrandComponent implements OnInit {
constructor() { }
ngOnInit() {
const injector = Injector.create({
// 描述创建方式
providers: [
{
provide: Product,
// useClass: Product
useFactory: () => {
return new Product("iPhone", "blue");
},
deps: []
},
{
provide: PurchaseOrder,
useClass: PurchaseOrder,
deps: [Product]
}
]
});
console.log(injector.get(Product));
console.log(injector.get(PurchaseOrder));
}
}
或者:
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SharedModule } from './shared/shared.module';
import localZh from '@angular/common/locales/zh-Hans';
import { registerLocaleData } from '@angular/common';
import { HomeService } from './home/services';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
SharedModule,
AppRoutingModule,
HomeModule,
],
providers: [
// PurchaseOrder,
// {
// provide: Product,
// // useClass: Product,
// useFactory: () => {
// return new Product("one day");
// },
// // 描述依赖性
// deps: []
// }
],
bootstrap: [AppComponent]
})
export class AppModule {
}
Angular提供的方式:
src\app\home\services\home.service.ts:
import { Injectable } from '@angular/core';
import { Channel, ImageSlider, TopMenu } from 'src/app/shared/components';
// @Injectable({ providedIn: 'root' })
@Injectable()
export class HomeService {
constructor() {
}
topMenus: TopMenu[] = [
{
title: '热门',
link: 'hot',
id: 1
},
{
id: 2,
title: '男装',
link: 'men'
},
{
id: 3,
title: '百货',
link: 'department'
}
];
getTopMenus() {
return this.topMenus;
}
}
src\app\home\components\home-container\home-container.component.ts:
import { Component, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { TopMenu, ImageSliderComponent } from 'src/app/shared/components';
import { HomeService } from '../../services';
@Component({
selector: 'app-home-container',
templateUrl: './home-container.component.html',
styleUrls: ['./home-container.component.scss']
})
export class HomeContainerComponent implements OnInit {
constructor(private homeService: HomeService) { }
ngOnInit() {
this.topMenus = this.homeService.getTopMenus();
}
topMenus: TopMenu[] = [];
}
src\app\home\home.module.ts:
import { NgModule } from '@angular/core';
import { HomeRoutingModule } from './home-routing.module';
import { SharedModule } from '../shared/shared.module';
import { HomeContainerComponent, HomeDetailComponent } from './components';
import { HomeService } from './services';
@NgModule({
declarations: [HomeContainerComponent, HomeDetailComponent],
providers: [HomeService], // <--here
imports: [
HomeRoutingModule,
SharedModule,
]
})
export class HomeModule { }
注入值:
src\app\home\components\home-grand\index.ts:
import { InjectionToken } from '@angular/core';
export const token = new InjectionToken<string>('baseUrl');
src\app\home\components\home-grand\home-grand.component.ts:
import { Component, Inject, Injectable, InjectionToken, Injector, OnInit } from '@angular/core';
import { token } from '.';
@Component({
selector: 'app-home-grand',
templateUrl: './home-grand.component.html',
styleUrls: ['./home-grand.component.scss']
})
export class HomeGrandComponent implements OnInit {
constructor(@Inject(token) private baseUrl: string) { }
ngOnInit() {
const injector = Injector.create({
// 描述创建方式
providers: [
{
// provide: 'baseUrl',
provide: this.baseUrl, // 使用Token
useValue: 'http://127.0.0.1'
}
]
});
console.log("baseUrl: " + injector.get('baseUrl'));
}
}
脏值检测
src\app\home\components\child\child.component.ts:
import { formatDate } from '@angular/common';
import { Component, ElementRef, NgZone, OnInit, Renderer2, ViewChild } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit {
private _title: string;
private _time: number;
public get title(): string {
console.log("脏值检测");
return this._title;
}
public get time(): number {
return this._time;
}
constructor(private ngZone: NgZone, private rd: Renderer2) {
this._title = 'hi';
this._time = Date.now();
}
@ViewChild('timeRef', { static: true }) timeRef!: ElementRef;
ngOnInit() {
}
ngAfterViewChecked(): void {
// this._title = 'nihao'; // 抛出异常
// angular之外运行
this.ngZone.runOutsideAngular(() => {
// 异步
setInterval(() => {
this._title = 'nihao';
this._time = Date.now();
// this.timeRef.nativeElement.innerText = Date.now();
this.rd.setProperty(this.timeRef.nativeElement, 'innerText',
// Date.now()
// 使用管道操作日期格式
formatDate(Date.now(), 'HH:mm:ss:SSS', 'zh-Hans')
);
}, 100);
});
}
handleClick() {}
}
src\app\home\components\child\child.component.html:
<p>
child works!
</p>
<hr>
<span [textContent]="title"></span>
<hr>
<span [textContent]="time | date: 'HH:mm:ss:SSS'"></span>
<hr>
<button (click)="handleClick()">触发脏值检测</button>
<br>
<span>倒计时-直接操作DOM而不是采用绑定: </span>
<span #timeRef></span>
OnPush策略:
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ImageSlider } from 'src/app/shared/components';
import { Channel } from 'src/app/shared/components/horizontal-grid';
import { HomeService } from '../../services';
@Component({
selector: 'app-home-detail',
templateUrl: './home-detail.component.html',
styleUrls: ['./home-detail.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush // OnPush策略
})
export class HomeDetailComponent implements OnInit {
constructor(private route: ActivatedRoute,
private homeService: HomeService,
private cd: ChangeDetectorRef
) { }
selectedTabLink: string | null | undefined;
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.selectedTabLink = params.get('tabLink');
this.cd.markForCheck(); // 手动检查
});
this.imageSliders = this.homeService.getImageSliders();
this.channels = this.homeService.getChannels();
}
imageSliders: ImageSlider[] = [];
channels: Channel[] = [];
}