引入ng-zorro-antd最好最好最好用自动构建的方式,也即是通过ng add ng-zorro-antd,的方式
通过add ng-zorro-antd的方式不需要在styles.css中引入样式和angular.json中引入样式等繁琐的步骤,如果用手动方式,会有很多的问题,好处就是可以直接在页面中引入antd的组件,比如,<button nz-button class="login-form-button login-form-margin" [nzType]="'primary'">Log in</button>等,但是我们需要在相应的页面的@components({imports:[NzButtonModule]})需要使用的module,这样样式才会生效。ng g program生成的项目中没有了app.moudles.ts,对于我们经常要用的module,我们可以用一个share.module.ts收集所有的module。最后在需要引用的页面的@Component({imports: [CommonModule,ShareModule],})即可
1 新版路由守卫由于canActivate已被废弃,采用函数函数,但其参数中无法像类一样进行路由对象注入,如何实现路由首位中的页面跳转?
import { CanActivateFn, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { inject } from "@angular/core"
export const authguardGuard: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
console.log("route", route)
console.log("state", state)
const router: Router = inject(Router)
if (localStorage.getItem("token")) {
if (state.url == '/login') {
router.navigate(['/home'])
return true
} else {
return true
}
} else {
console.log("1")
if (state.url !== "/login") {
router.navigate(['/login'])
}
return true
}
};
这里采用inject强制注入得到router对象。这样就可以实现路由的跳转
2 对于路由懒加载方式,需要在app.module.ts和当前module.ts中同时引入相关模块。否则会报错。比如
'nz-form-control' is not a known element:
原因就是NzFormModule只在app.moudule.tsz中引入了,但是却没有在当前页面的组件的module中引入导致一直报错
3 nozzor-antd中的nz-space组件要想生效,必须加入*nzSpaceItem
4 模板中遍历的数据如何获取当前对象的属性值,如下:
constructor(private fb:FormBuilder){
this.validateForm=this.fb.group({
storename:[''],
tableSize:this.fb.group({
toggle:['true'],
groupSize:this.fb.array([
this.fb.group({
cate:['indoor'],
title_en:[''],
title_zh:[''],
}),
this.fb.group({
cate:['outdoor'],
title_en:[''],
title_zh:[''],
}),
]),
}),
})
}
<form class="store_generate_form" nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
<nz-form-item>
<nz-form-label [nzSpan]="8" nzFor="storename">店铺名称</nz-form-label>
<nz-form-control [nzSpan]="16">
<input nz-input name="storename" type="storename" formControlName="storename">
</nz-form-control>
</nz-form-item >
<div>
<nz-form-item>
<nz-tab [nzTitle]="group.value.cate" *ngFor="let group of groupSize.controls; let i = index" [formGroupName]="i">
</nz-form-item>
</div>
这里的tab标签页的tab的名称要根据cate字段来读取。这里的方式是通过[nzTitle]="group.value.cate"来获取的。对于每一个control而言,其下都有一个value属性,通过value属性就可以获取到原始的json数据对象
6 zorro中如何实现tabs标签页添加额外内容?
<nz-tabset nzType="card" formArrayName="groupSize"
[nzTabBarExtraContent]="extraContent" (nzAdd)="addTab()"
>
<ng-template #extraContent>
<button nz-button nzType="dashed">Add</button>
</ng-template>
<nz-tab nzIcon="book" >
<ng-template nz-tab>
tab中的内容xxxx
</ng-template>
</nz-tab>
<ng-container *ngTemplateOutlet="extraContent"></ng-container>
</nz-tabset>
通过定义tabExtraContent
模板引用,其中包含自定义的文本内容。然后,在nz-tabset
内部使用<ng-container>
元素,并使用*ngTemplateOutlet
指令将tabExtraContent
引用的内容渲染在页面指定位置。
通过这种方式,你可以将默认的"+"样式替换为自定义的文本("Add"按钮),并在页面中正确渲染。
7 给formArray对象添加group数据的时候,切记每一项的字段名称要对应,否则会报错
RROR Error: Cannot find control with path: 'tableSize -> groupSize -> 0 -> tableSize -> 2 -> minPerson'
例如:
<nz-tab nzIcon="book" [nzTitle]="group.value.cate" *ngFor="let group of groupSize.controls; let i = index" [formGroupName]="i">
<div formArrayName="tableSize">
<ng-template nz-tab>
<nz-form-item *ngFor="let table of tableSizeControls(i)?.['controls']; let j = index" [formGroupName]="j">
<nz-form-control>
<div class="danamic_group">
<div class="danamic_group_item">
<nz-input-group nzAddOnBefore="Key" >
<input nz-input type="text" nz-input formControlName="size"/>
</nz-input-group>
</div>
<div class="danamic_group_item" >
<nz-input-group nzAddOnBefore="EN" >
<input nz-input type="text" nz-input formControlName="desc_en"/>
</nz-input-group>
</div>
<div class="danamic_group_item" >
<nz-input-group nzAddOnBefore="CH">
<input nz-input type="text" nz-input formControlName="desc_zh"/>
</nz-input-group>
</div>
<div class="danamic_group_item" >
<nz-input-group nzAddOnBefore="number">
<input nz-input type="text" nz-input formControlName="number"/>
</nz-input-group>
</div>
<div class="danamic_group_item" >
<nz-input-group >
<nz-input-number [nzMin]="1" type="text" nz-input formControlName="minPerson"/>
</nz-input-group>
</div>
<div class="danamic_group_item">
<nz-input-group >
<nz-input-number [nzMin]="1" type="text" nz-input formControlName="maxPerson"/>
</nz-input-group>
</div>
</div>
</nz-form-control>
</nz-form-item>
</ng-template>
</div>
</nz-tab>
注意在ngfor中最后两个formControlName分别是minPerson和maxPerson,接下来在js文件中给formArray添加一条新的数据
get groupSize(): FormArray {
return this.validateForm.get('tableSize.groupSize') as FormArray;
}
tableSizeControls(index:number): FormArray {
let list=this.validateForm.get('tableSize.groupSize') as FormArray;
let lastlist=list.controls[index].get('tableSize') as FormArray ||[]
return lastlist
}
add(){
//先找到是indoor还是outdoor的tablsesize
console.log("this.activeTab",this.actvieTabIndex)
let newdata=this.fb.group({
size: [""],
desc_en:[""],
desc_zh: [""],
number:[''],
preTitle: [""],
maxPerson: [],
})
let curTableSizeArr=this.tableSizeControls(this.actvieTabIndex) as FormArray
console.log("curTableSizeArr",curTableSizeArr)
curTableSizeArr.push(newdata)
console.log("curTableSizeArr",curTableSizeArr)
}
remove(){
let curTableSizeArr=this.tableSizeControls(this.actvieTabIndex) as FormArray
curTableSizeArr.removeAt(curTableSizeArr.length-1)
}
注意我们在add函数中定义的数据newdata其中的字段,没有minPerson,此时就会报错。此时需要我们核实字段。我们更改perTtile为minPerson以后。报错消失
8 angular中拦截器如何简化后端返回的数据?
如果后端返回的数据层级过深,如何简化层级,在具体的请求中得到简化后的数据?
@Injectable()
export class AuthInterceptorInterceptor implements HttpInterceptor {
constructor() {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
let reqClone=request.clone({
setHeaders:{token:localStorage.getItem("token")||""}
})
return next.handle(reqClone).pipe(
map((event:any)=>{
if(event instanceof HttpResponse){
event=event.clone({body:event.body.data.data.data})
}
return event
}),
catchError((err:HttpErrorResponse)=>{
console.log("err",err);
throw err
})
)
}
}
核心在map这个函数。同时要注意我们对返回值要更改的话要通过clone方式,直接更改event无效
9:app.module.ts引入了ReactiveFormsModule和FormsModule,但是依旧报错:Can't bind to 'formGroup' since it isn't a known property of 'form'.
原因:没有在app.module.ts中申明页面组件
@NgModule({
declarations: [
AppComponent,
LayoutComponent,
HomeComponent,
NewsComponent,
NotfoundComponent,
StoreformComponent,
AboutComponent,
LoginComponent,
FormpageComponent //注意这里
// AdminComponent
],
10:ERROR NullInjectorError: R3InjectorError(StoreEditModule)[NzMessageService -> NzMessageService -> NzMessageService -> NzMessageService]:
NullInjectorError: No provider for NzMessageService!
在引入NzMessageService时。报错。此原因在于没有在当前模块的privide选项中进行设置:
constructor(private fb:FormBuilder,private message:NzMessageService){
this.validateForm=this.fb.group({
storename:[''],
})
}
ngOnInit(){
const id = this.message.loading('加载中..', { nzDuration: 0 }).messageId;
setTimeout(() => {
this.message.remove(id);
//回显赋值
//this.validateForm.patchValue(data)
}, 3000);
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StoreEditRoutingModule } from './store-edit-routing.module';
import { StoreEditComponent } from './store-edit.component';
import { ReactiveFormsModule, FormsModule, FormGroup, FormBuilder, FormArray } from '@angular/forms';
import { NzFormModule} from 'ng-zorro-antd/form';
import { NzMessageService } from 'ng-zorro-antd/message';
@NgModule({
declarations: [
StoreEditComponent
],
imports: [
CommonModule,
StoreEditRoutingModule,
NzBreadCrumbModule,
],
providers: [{provide: NzMessageService}], //这里是核心
})
export class StoreEditModule { }