1、路由传参
1.1 传参
queryParams:
this.router.navigate(['pages/xxlJob/joblog'], {queryParams: {title: '查看调度日志[' + row.jobDesc + ']', jobId: row.id, jobGroup: row.jobGroup}});
1.2 接收参数
1.2.1 构造函数注入 ActivatedRoute
private activatedRoute: ActivatedRoute
1.2.2 解析参数
this.activatedRoute.queryParams.subscribe((value: any) => {
this.jobid = value.jobId;
this.jobgroup = value.jobGroup;
});
2、在当前组件打开一个新的组件
假设当前组件为 JobLogComponent,要打开的组件为 JobLogDetailComponent
2.1 父组件模板添加存放子组件的容器
<ng-container #joblogdetail></ng-container>
2.2 父组件声明子组件容器的引用
@ViewChild('joblogdetail', { read: ViewContainerRef })
conRef: ViewContainerRef;
2.3 父组件注入必要的组件
private resolver: ComponentFactoryResolver,
private injector: Injector,
2.4 父组件打开子组件的事件
public edit(row: any) {
this.showLogDetail = true;
if (this.conRef) {
this.conRef.clear(); // 删除之前的视图
}
const ss: StandService = new StandService();
ss.service = row;
const myInjector = Injector.create({ providers: [{ provide: StandService, deps: [], useValue: ss}], parent: this.injector });
const factory = this.resolver.resolveComponentFactory(JobLogDetailComponent);
const comref: ComponentRef<JobLogDetailComponent> = this.conRef.createComponent(factory, 0, myInjector);
comref.instance.backMain.subscribe(() => {
this.conRef.clear();
this.showLogDetail = false;
});
}
2.5 StandService 自定义参数注入组件
import { Injectable } from '@angular/core';
@Injectable()
export class StandService {
service: any;
}
2.6 子组件声明 点击事件用于返回父组件
@Output() backMain = new EventEmitter();
2.7 子组件构造函数注入参数,并接受参数
如果父组件不传参数给子组件可忽略
private ss: StandService,
this.executorAddress = ss.service.executorAddress;
this.triggerTime = ss.service.triggerTime;
this.logId = ss.service.id;
2.8 子组件返回键
<button nz-button [nzType]="'primary'" (click)="backMain.next()">
<i nz-icon nzType="arrow-left" nzTheme="outline"></i>
返回
</button>
3 angular 升级到 9后,post 中文乱码
3.1 原发生乱码的代码
editRow(rowData: Resource): Observable<any> {
const postUrl = this.apiUrl + 'resource/edit';
let body = 'resId=' + rowData.resId
+ '&resName=' + rowData.resName
+ '&resType=' + rowData.resType
+ '&resUrl=' + rowData.resUrl
+ '&resIcon=' + (rowData.resIcon ? rowData.resIcon : '')
+ '&seqSort=' + rowData.seqSort
+ '&remark=' + (rowData.remark ? rowData.remark : '');
if (!(rowData.resPid === null || rowData.resPid === undefined) && rowData.resPid.toString() !== 'null') {
body += '&resPid=' + rowData.resPid;
}
return this.http.post(postUrl, body, {
headers: this.headers
});
}
3.2 修改后的代码
editRow(rowData: Resource): Observable<any> {
const postUrl = this.apiUrl + 'resource/edit';
const body = new HttpParams()
.set('resName', rowData.resName)
.set('resId', rowData.resId.toString())
.set('resType', rowData.resType.toString())
.set('resUrl', rowData.resUrl)
.set('resIcon', (rowData.resIcon ? rowData.resIcon : ''))
.set('seqSort', rowData.seqSort.toString())
.set('validity', (rowData.validity ? rowData.validity : ''))
.set('remark', (rowData.remark ? rowData.remark : ''));
if (!(rowData.resPid === null || rowData.resPid === undefined) && rowData.resPid.toString() !== 'null') {
body.set('resPid', rowData.resPid.toString());
}
return this.http.post(postUrl, body, {
headers: this.headers
});
}
4 自定义字段校验规则
4.1 自定义校验函数
confirmPasswd(pwd: string): ValidatorFn {
return (control) => {
if (!control.value) {
return { error: true, required: true };
} else if (control.value !== control.parent.controls[pwd].value) {
return { confirm: true, error: true };
}
return {};
};
}
其中 返回 confirm 是要在表单要用到的错误处理字段,为true表示密码不一致,参数表示要与之比较的字段
4.2 表单定义
this.sysAddForm = this.fb.group({
sysId: ['', [Validators.required]],
sysUserPassword: ['', [Validators.required, Validators.pattern('(?=.*\\d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,30}')]],
sysUserPasswordConfirm: ['', this.pagesService.confirmPasswd('sysUserPassword') ],
content: [''],
sysUserName: ['', Validators.required, Validators.pattern('^[A-Za-z][A-Za-z_]+[A-Za-z]$')],
id: [null]
});
4.3 错误展示
<nz-form-control [nzSpan]="18" [nzErrorTip]="sysUserPasswordConfirm">
<input autocomplete="new-password" type="password" nz-input formControlName="sysUserPasswordConfirm"/>
<ng-template #sysUserPasswordConfirm let-control>
<ng-container *ngIf="control.hasError('required')">
确认密码不能为空!
</ng-container>
<ng-container *ngIf="control.hasError('confirm')">
密码不一致!
</ng-container>
</ng-template>
</nz-form-control>
5 全局模板
有时候很多地方会用到同一种模板,这时候有必要创建全局模板,方便管理维护,万一要更改也方便
5.1 定义全局模板组件
@Component({
selector: 'app-global-templates',
templateUrl: './global-templates.component.html',
styleUrls: ['./global-templates.component.less']
})
export class GlobalTemplatesComponent {
@ViewChild('rangeTemplate', {static: true})
rangeTemplate!: TemplateRef<void>;
@ViewChild('nzIndicatorTpl', {static: true})
nzIndicator!: TemplateRef<void>;
}
html
<ng-template #nzIndicatorTpl>
<div id="preloader">
<div>
<div class="cares-logo"></div>
</div>
</div>
</ng-template>
<ng-template #rangeTemplate let-range="range" let-total>
第 {{ range[0] }}-{{ range[1] }} 条 / 共 {{ total }} 条
</ng-template>
5.2 将模板注入全局service 作为组件的变量
indicatorTemplate!: TemplateRef<void>;
rangeTemplate!: TemplateRef<void>;
5.3 全局service实例化模板并赋值
constructor(
injector: Injector,
resolver: ComponentFactoryResolver
) {
const factory = resolver.resolveComponentFactory(GlobalTemplatesComponent);
const {rangeTemplate} = factory.create(injector).instance;
const {nzIndicator} = factory.create(injector).instance;
this.rangeTemplate = rangeTemplate;
this.indicatorTemplate=nzIndicator;
}
5.4 引用
配置全局加载指示器
const nzConfigFactory = (
pagesService: PagesService,
): NzConfig => {
const nzIndicator = pagesService.indicatorTemplate;
return {
spin: {
nzIndicator
},
message: {nzTop: 120},
notification: {nzTop: 120}
};
};
providers: [
{provide: NZ_CONFIG, useFactory: nzConfigFactory, deps:[PagesService]},
{provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true},
],
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!