npm install -g @angular/cli
ng new my-app --routing --style less
(--routing 帶有路由模塊,--style less 樣式表爲less)
ng serve -p 4800 --aot --host 0.0.0.0 --disable-host-check true
(-p 啓動端口4800 --disable-host-check true 開啓端口檢查 --aot aot編譯)
ng build --prod -nc
(--prod 成產模式 -nc chunks以模塊名命名)
@Component({
selector: 'app-index',//選擇器
encapsulation: ViewEncapsulation.None,//Emulated 默認 Native 私有沒法訪問 None 不處理
styleUrls: ['./index.component.less'],//樣式表連接
styles: ['.primary {color: red}'],
viewProviders:[],//依賴模塊
providers:[],//依賴服務
exportAs:'appIndex',//模塊導出標識
//templateUrl: './index.component.html',//模板連接
template:"<div>{{msg}}</div>",
host:{
'[class.test]': 'true',
'[attr.id]': ''test'',
}
})
export class IndexComponent{
constructor() {
}
@ViewChild('movieplayer') movieplayerRef:ElementRef//獲取當前dom實例。
msg:string = 'hello angular';
clickTest(){}
list:Array<any> = [1,2,3,4,5];
show:boolean = true;
word:string
width:number = 100;
showTest:boolean = true;
@Output() myEvent = new EventEmitter<any>();
@Input() myProperty;
_my2Property
@Input() set my2Property(val){
this._my2Property = val;
};
get my2Property(){
return this._my2Property;
}
}複製代碼
<app-index [myProperty]="{a:1}" (myEvent)="$event.stopPropagation()" #indexRef="appIndex"></app-index>複製代碼
[]
屬性綁定
()
事件綁定
*ngFor
列表渲染
*ngIf
條件渲染
[(ngModel)]
雙向綁定
#xxxx
局部變量
<div
[title]="msg"
(click)="clickTest($event)"
[style.width.px]="width"
[ngStyle]="{'width.%':width}"
[ngClass]="{'class-test':showTest}"
[class.class-test]="showTest"
*ngFor="let li of list;let i = index;trackBy: trackById"
*ngIf="show">
<input type="text" [(ngModel)]="word">
{{word}}
</div>
<video #movieplayer></video>
<button (click)="movieplayer.play()">
<ng-template ngFor [ngForOf]="list" let-li let-i="index" let-odd="odd" [ngForTrackBy]="trackById"></ng-template>
<ng-template [ngIf]="show"></ng-template>
<div [ngSwitch]="conditionExpression">
<template [ngSwitchCase]="case1Exp"></template>
<template ngSwitchCase="case2LiteralString"></template>
<template ngSwitchDefault></template>
</div>複製代碼
const routes: Routes = [
{
path:'',
component:IndexComponent,
resolve:{resolve:ResolverService},
canActivate:[AuthGuard],
data:{},
}
]
@NgModule({
imports: [RouterModule.forRoot(routes,{useHash: true})],
exports: [RouterModule]
})
export class IndexRoutingModule {
}複製代碼
@Injectable()
export class CurrentResolverService implements Resolve<any> {
constructor(private router: Router, private userService_: UserService) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
//1.
return Observable.create({})
//2.
return new Promise((resolve, reject) => {
setTimeout(()=> {
resolve({})
},2000)
})
//3.
return {}
}
}
複製代碼
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
constructor() {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
//1.
return Observable.create(false)
//2.
return new Promise((resolve, reject) => {
setTimeout(()=> {
resolve(false)
},2000)
})
//3.
return false
}
//子路由守護
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.canActivate(childRoute, state);
}
//異步加載組件
canLoad(route: Route): Observable<boolean> | Promise<boolean> | boolean {
return null;
}
}複製代碼
<router-outlet></router-outlet>
<router-outlet name="aux"></router-outlet>複製代碼
<a routerLink="/path" [routerLinkActive]="'active'">
<a [routerLink]="[ '/path', routeParam ]">
<a [routerLink]="[ '/path', { matrixParam: 'value' } ]">
<a [routerLink]="[ '/path' ]" [queryParams]="{ page: 1 }">
<a [routerLink]="[ '/path' ]" fragment="anchor">複製代碼
ngOnChanges
當組建綁定數據發生改變將會觸發今生命週期
//OnChanges
ngOnChanges(changes: SimpleChanges): void {
let value = changes.test && changes.test.currentValue
}複製代碼
ngOnInit
在調用完構造函數、初始化完全部輸入屬性
//OnInit
ngOnInit(): void{
}複製代碼
ngDoCheck
每當對組件或指令的輸入屬性進行變動檢測時就會調用。能夠用它來擴展變動檢測邏輯,執行自定義的檢測邏輯。
//DoCheck
ngDoCheck(): void {
console.info('ok')
}複製代碼
ngOnDestroy
只在實例被銷燬前調用一次。
//OnDestroy
ngOnDestroy(): void {
console.info('ok')
}複製代碼
@Injectable()
export class TestService {
constructor() {
}
private data = {num:1};
get num(){
return this.data.num
}
add(){
++this.data.num
}
minus(){
--this.data.num
}
}複製代碼
providers
中便可
@NgModule({
providers:[
TestService
]
})複製代碼
@Component({
providers:[
TestService
]
})複製代碼
TestService
實例,並把它存到名爲
_testService
的私有屬性中
export class IndexComponent{
constructor(private _testService:TestService) {
}
}複製代碼
@Injectable()
export class Test2Service extend TestService{
constructor() {
super();
}
}
@Component({
providers:[
{ provide: TestService, useClass: Test2Service}
],//依賴服務
})
export class IndexComponent{
constructor(private _testService:TestService) {
}
}複製代碼
HttpModule
模塊 變動爲
HttpClientModule
。
HttpClientModule
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
CommonModule,
FormsModule,
HttpClientModule,
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule {
} 複製代碼
HttpClient
服務。
request(method: string, url: string, options: {
body?: any;
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'any';
withCredentials?: boolean;
}): Observable<any>;
get(url: string, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'any';
withCredentials?: boolean;
}): Observable<any>;
post(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'any';
withCredentials?: boolean;
}): Observable<any>;複製代碼
//定義接口返回的參數字段 通常接口返回的參數都是固定的
export interface Result<T> {
result?: any
success?: any
message?: any
}複製代碼
export class ConfigService {
static baseUrl = 'http://127.0.0.1:8080';
static uploadPath = 'http://127.0.0.1:8080';
constructor(private _http: HttpClient) {
}
configForm() {
return new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
}
/**
* @deprecated 直接經過FormData處理
*/
configFormData() {
return new HttpHeaders().set('Content-Type', 'multipart/form-data');//;charset=UTF-8
}
configJson() {
return new HttpHeaders().set('Content-Type', 'application/json;charset=UTF-8');
}
postForm<T>(url, body = {}, config = {}): Observable<Result<T>> {
return this._http.post<T>(ConfigService.baseUrl + url, qs.stringify(body), {headers: this.configForm(), ...config})
}
postFormData<T>(url, body = {}, config = {}): Observable<Result<T>> {
const f = new FormData();
for (let i in body) {
f.append(i, body[i]);
}
return this._http.post<T>(ConfigService.baseUrl + url, f, {...config})
}
postFormDataUpload<T>(url, body = {}, config = {}): Observable<Result<T>> {
const f = new FormData();
for (let i in body) {
if(body.hasOwnProperty(i)) f.append(i, body[i]);
}
return this._http.post<T>(ConfigService.uploadPath + url, f, {...config})
}
postJson<T>(url, body = {}, config = {}): Observable<Result<T>> {
return this._http.post<T>(ConfigService.baseUrl + url, body, {headers: this.configJson(), ...config})
}
get<T>(url, body: any = {}, config = {}): Observable<Result<T>> {
return this._http.get<T>(`${ConfigService.baseUrl + url}?${qs.stringify(body)}`, config)
}
}複製代碼
url, body, config
。方便管理。若是項目龐大,能夠多加幾個服務,按照模塊劃分,不一樣的模塊由不一樣的
service
服務。
@Injectable()
export class UserService extends ConfigService {
constructor(_http: HttpClient) {
super(_http);
}
/**
* 退出
* @returns {Observable<Result<any>>}
*/
quit() {
return this.get(`url`)
}
/**
* 登陸
* @returns {Observable<Result<any>>}
*/
login(body = {},config = {}) {
return this.postJson(`url`, body, config)
}
/**
* 註冊
* @returns {Observable<Result<any>>}
*/
register(body = {},config = {}){
return this.postForm('url', body, config);
}
}
複製代碼
window.addEventListener('fetch',(event)=> {})
這個監聽事件。官網文檔
移步
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
constructor() {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
req = req.clone({headers: req.headers});
let xhr = next.handle(req);
return xhr
.do(response => {
if (response instanceof HttpResponse) {
if (response.type == 4) {
if (response.status == 200) {
//...統一的邏輯處理,好比彈幕提示
} else if (response.status == 500) {
//...統一的錯誤處理
}
}
}
}).catch(error => {
return Observable.throw(error || "Server Error");
})
}
}複製代碼
使用方法以下,這樣全部的接口請求都會通過NoopInterceptor
類。
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
CommonModule,
FormsModule,
HttpClientModule,
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: NoopInterceptor,
multi: true,
}
],
bootstrap: [AppComponent]
})
export class AppModule {
} 複製代碼
@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
/**
* @value 預處理的值
* @args 參數數組 {{value | keys:xxx:xxxx}} xxx、xxxx就是參數
* @return 必需要有返回值
*/
transform(value, args: string[]): any {
let keys = [];
for (let key in value) {
keys.push({key: key, value: value[key]});
}
return keys;
}
}複製代碼
純(pure)管道與非純(impure)管道
//默認是純Pipe
@Pipe({
name: 'keys',
pure: true,
})
//非純Pipe
@Pipe({
name: 'keys',
pure: false,
})複製代碼
BrowserAnimationsModule
。
@NgModule({
imports: [ BrowserModule, BrowserAnimationsModule ],
})
export class AppModule { }複製代碼
import {animate, style, transition, trigger} from '@angular/animations';
export const fadeIn = trigger('fadeIn', [
transition('void => *', [
style({opacity: 0}),
animate(150, style({opacity: 1}))
]),
transition('* => void', [
animate(150, style({opacity: 0}))
])
]);
/**
* 使用方式
*/
@Component({
animations:[fadeIn],
template: `
<div [@fadeIn]></div>
`,
})
export class IndexComponent{
constructor() {
}
}複製代碼
NgModule
,直接上代碼。
@Component({
selector: 'app-user-list',
templateUrl: './user-list.component.html',
encapsulation: ViewEncapsulation.None,//html不作任何處理
styleUrls: ['./user-list.component.less']
})
export class UserListComponent implements OnInit {
}複製代碼
const routes = [
{
path: '',
children:[
{
path: 'userList',
component: UserListComponent
},
]
}
]
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserRoutingModule {
}複製代碼
@NgModule({
declarations: [
UserListComponent,
],
imports: [
UserRoutingModule
],
providers: [],
})
export class UserModule {
}複製代碼
const routes = [
{
path: '',
component: IndexComponent,
children:[
{
path: 'user',
loadChildren: 'app/user/user.module#UserModule',
},
]
}
]
@NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})],
exports: [RouterModule]
})
export class AppRoutingModule {
}複製代碼
<p class="selected-text">
當前已選擇:
<span>{{result().length}}</span>個
</p>
<div class="tags-box">
<ul class="clearfix data-tags">
<li *ngFor="let rl of resultList;let index = index">
{{rl.name}}
<i class="yc-icon icon" (click)="removeResultList(rl)">X</i>
</li>
</ul>
</div>
<div class="select-list-inner">
<div class="scope" *ngFor="let list of cacheList;let index1 = index" [ngStyle]="{'width.%':100.0 / cacheList.length}">
<ul class="list-with-select">
<li class="spaui" *ngFor="let l of list;let index2 = index" (click)="pushCache(index1,index2,list)">
<app-checkbox [(ngModel)]="l.selected" (eventChange)="areaItemChange(l)" [label]="l.name" [checkState]="l.checkState" [not_allow_selected]="l[hasCheckbox]"></app-checkbox>
<i *ngIf="l[child]?.length > 0" class="icon yc-icon"></i>
</li>
</ul>
</div>
</div>複製代碼
.select-list-inner {
background: #fff;
width: 100%;
border: 1px solid #ddd;
max-height: 272px;
overflow: auto;
display: flex;
.scope {
&:first-child {
border-left: none;
}
flex: auto;
width: 0;
overflow: auto;
max-height: 270px;
transition: width .2s;
border-left: 1px solid #dfe1e7;
.list-with-select {
margin: 10px 0;
.spaui {
&:hover {
background: #f8f9fa;
}
height: 40px;
line-height: 40px;
padding-left: 20px;
width: 100%;
cursor: pointer;
font-size: 15px;
position: relative;
> i {
float: right;
padding-right: 20px;
}
}
}
}
}
.tags-box {
position: relative;
border-top: 1px solid transparent;
border-bottom: 1px solid transparent;
margin-bottom: 10px;
overflow-y: auto;
max-height: 202px;
overflow-x: hidden;
transition: height .2s ease-in-out;
ul.data-tags {
width: 100%;
position: relative;
margin-bottom: 10px;
li {
float: left;
margin-right: 5px;
border: 1px solid #dfe1e7;
border-radius: 20px;
background: #f0f3f6;
height: 34px;
line-height: 32px;
padding-left: 24px;
padding-right: 8px;
margin-top: 10px;
font-size: 14px;
transition: padding .2s ease-in-out;
.icon {
opacity: 0;
transition: opacity .2s;
}
&:hover {
background: #e1e7f1;
padding-left: 16px;
padding-right: 16px;
transition: padding .2s ease-in-out;
.icon {
opacity: 1;
transition: opacity .2s;
cursor: pointer;
}
}
}
}
}
.selected-text {
float: left;
line-height: 55px;
padding-right: 10px;
> span {
font-size: 16px;
font-weight: 700;
color: #ff5e5e;
}
}
複製代碼
import {Component, EventEmitter, forwardRef, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";
const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DirectionalSelectComponent),
multi: true
};
@Component({
selector: 'directional-area-select',
exportAs: 'directionalAreaSelect',
templateUrl: './directional-select.component.html',
styleUrls: ['./directional-select.component.less'],
providers: [
CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR
]
})
export class DirectionalSelectComponent implements OnInit, ControlValueAccessor {
constructor() {
}
onChange = (value: any) => {
};
writeValue(obj: any): void {
if (obj instanceof Array && obj.length > 0) {
this.filterFill(obj);
this.resultList = this.result(3);
}
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
}
ngOnInit() {
}
resultList;
cacheList: any[] = [];
private list: any[] = [];
inputListChange() {
if (this._inputList instanceof Array && this._inputList.length > 0) {
this.list = this._inputList.map(d => {
this.recursionChild(d);
return d;
});
this.cacheList.length = 0;
this.cacheList.push(this.list);
}
}
_inputList;
@Input('firstNotSelect') firstNotSelect = false;
@Input('inputList') set inputList(value) {
this._inputList = value;
this.inputListChange();
}
@Input('value') value;
@Input('hasCheckbox') hasCheckbox = 'not_allow_selected';
@Input('child') child = 'options';
@Output('eventChange') eventChange = new EventEmitter<any>();
/**
* 顯示對應的子集數據列表
* @param index1 當前層數下標
* @param index2 當前層數列表的下標
* @param list 當前層的列表數據
*/
pushCache(index1, index2, list) {
//日後選擇
let cl = this.cacheList[index1 + 1];
let child = list[index2][this.child];
if (child instanceof Array && child.length > 0) {
if (!cl) {
this.cacheList.push(child);
} else {
if (cl !== child) {
this.cacheList.splice(index1 + 1, 1, child)
}
}
} else {
if (cl !== child && !(child instanceof Array)) {
this.cacheList.pop();
}
}
//往前選擇
if (child && child.length > 0) {
while (this.cacheList.length > index1 + 2) {
this.cacheList.pop();
}
}
}
removeResultList(data) {
data.selected = false;
this.areaItemChange(data);
}
//選中有幾個狀態 對於父節點有 1所有選中 2部分選中 3所有取消 checkState 1 2 3
areaItemChange(data) {
if (data[this.hasCheckbox]) return;
let child = data[this.child];
if (data.selected) {
data.checkState = 1
} else {
data.checkState = 3
}
//向下尋找
if (child && child.length > 0) {
this.recursionChildCheck(child)
}
//向上尋找
this.recursionParentCheck(data);
this.resultList = this.result(3);
if (this.resultList instanceof Array && this.resultList.length > 0) {
this.onChange(this.resultList.map(r => r.id));
} else {
this.onChange(null);
}
this.eventChange.next();
}
/**
* 判斷當前對象的父級中的子集被選中的個數和checkState == 2的個數來肯定父級的當前狀態
* 遞歸
* @param data
*/
private recursionParentCheck(data) {
let parent = data.parent;
if (parent) {
let l = parent[this.child];
let length = l.reduce((previousValue, currentValue) => {
return previousValue + ((currentValue.selected) ? 1 : 0)
}, 0);
let length2 = l.reduce((previousValue, currentValue) => {
return previousValue + ((currentValue.checkState == 2) ? 1 : 0)
}, 0);
if (length == l.length) {
parent.checkState = 1;
parent.selected = true;
} else if (length == 0 && length2 == 0) {
parent.checkState = 3
} else {
parent.checkState = 2;
parent.selected = false;
}
this.recursionParentCheck(parent);
}
}
/**
* 同步子集和父級的狀態
* 遞歸
* @param list
*/
private recursionChildCheck(list) {
if (list && list.length > 0) {
list.forEach(data => {
let checked = data.parent.selected;
data.selected = checked;
if (checked) {
data.checkState = 1;
data.selected = true;
} else {
data.checkState = 3;
data.selected = false;
}
let l = data[this.child];
this.recursionChildCheck(l)
})
}
}
/**
* 子集包含父級對象
* 遞歸
*/
private recursionChild(target) {
let list = target[this.child];
if (list && list.length > 0) {
list.forEach(data => {
data.parent = target;
this.recursionChild(data)
})
}
}
/**
* type 1 獲取id集合 2獲取key value 3獲取對象引用
* @param {number} type
* @param {any[]} result
* @returns {any[] | undefined}
*/
result(type = 1, result = []) {
if (this.firstNotSelect) {
return this.recursionResult2(this.list, result, type);
}
return this.recursionResult(this.list, result, type);
}
/**
* 只獲取最後一層的值
* @param list
* @param {any[]} result
* @param {number} type
* @returns {any[] | undefined}
*/
private recursionResult2(list, result = [], type = 1) {
if (list && list.length > 0) {
list.forEach(data => {
let child = data[this.child];
if (child && child.length > 0) {
this.recursionResult2(child, result, type);
} else if (data.checkState == 1) {
switch (type) {
case 1:
result.push(data.id);
break;
case 2:
result.push({
id: data.id,
name: data.name,
});
break;
case 3:
result.push(data);
break;
}
}
})
}
return result;
}
private recursionResult(list, result = [], type = 1) {
if (list && list.length > 0) {
list.forEach(data => {
//所有選中而且父級沒有複選框
if ((data[this.hasCheckbox] && data.checkState == 1) || data.checkState == 2) {
let child = data[this.child];
if (child && child.length > 0) {
this.recursionResult(child, result, type);
}
//所有選中而且父級有複選框 結果不須要包含子集
} else if (data.checkState == 1 && !data[this.hasCheckbox]) {
switch (type) {
case 1:
result.push(data.id);
break;
case 2:
result.push({
id: data.id,
name: data.name,
});
break;
case 3:
result.push(data);
break;
}
}
})
}
return result;
}
filterFill(result) {
//運用數據特性 判斷時候選擇了國外的選項
this.cacheList.length = 1;
let bo = result.find(n => {
if (n == 1156 || String(n).length >= 6) return n
});
if (result instanceof Array && result.length > 0 && bo) {
let child = this.list[0][this.child];
while (child instanceof Array && child.length > 0) {
this.cacheList.push(child);
child = child[0][this.child];
}
} else {
let child = this.list[1][this.child];
while (child instanceof Array && child.length > 0) {
this.cacheList.push(child);
child = child[0][this.child];
}
}
this.recursionFilter(result, this.list)
}
//遞歸過濾知足條件對象
private recursionFilter(target, list, result = []) {
if (target instanceof Array && target.length > 0) {
list.forEach((data) => {
let child = data[this.child];
let bo = target.find((d => {
if (d == data.id) {
return d;
}
}));
if (bo) {
data.selected = true;
data.checkState = 1;
this.recursionChildCheck(child);
this.recursionParentCheck(data);
}
if (child instanceof Array && child.length > 0) {
this.recursionFilter(target, child);
}
})
}
}
}
複製代碼
cacheList
來儲存頂層父級數據做爲第一層,能夠查看
inputListChange
方法。
recursionChild
方法是將全部的子集包含本身的父級引用。
pushCache
顯示對應的子集數據列表
areaItemChange
當
checkbox
發生改變的時候就會觸發這個方法。這個方法完成的任務有向上尋找父級改變其狀態,向下尋找子集改變其狀態,將結果以標籤的形式羅列出來,對應的方法能夠查看
recursionChildCheck
recursionParentCheck
result(3)
ControlValueAccessor
類 ,可使用雙向綁定來獲取值。
上文也講到了路由守衛 auth.guard.ts
,這個類繼承了 CanActivate
、CanActivateChild
類。javascript
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
constructor() {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
//1.能夠將當前的訪問路由請求後臺訪問當前用戶是否有權限,或者能夠將權限存入本地緩存再進行判斷。
return Observable.create(false)
//2.
return new Promise((resolve, reject) => {
setTimeout(()=> {
resolve(false)
},2000)
})
//3.經過本地緩存判斷。
return false
}
//子路由守護 父路由啓用了子路由保護,進入自路由將會觸發這個回調函數。
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.canActivate(childRoute, state);
}複製代碼
app-routing.module.ts
const routes = [
{
path: '',
component: IndexComponent,
canActivate: [AuthGuard],
children:[
{
path: 'user',
loadChildren: 'app/user/user.module#UserModule',
},
]
}
]
@NgModule({
imports: [RouterModule.forRoot(routes, {useHash: true})],
exports: [RouterModule]
})
export class AppRoutingModule {
}複製代碼
user-routing.module.ts
const routes: Routes = [
{
path: '',
canActivateChild: [AuthGuard],//守護子路由
children: [
{
path: 'userlist',
component: UserListComponent,
resolve: {jurisdiction: CurrentResolverService},
data: {current: limitRole.userlist}
}
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserRoutingModule {
}複製代碼