页面组件
ABP提供了一个组件,可将您的内容与多个内置组件进行封装,从而减少需要编写的代码量。
如果某个组件的模板如下所示,您就可以使用abp-page组件。
我们先来看一个未使用abp-page组件的示例:
dashboard.component.ts
<div class="row entry-row">
<div class="col-auto">
<h1 class="content-header-title">{{ '::Dashboard' | abpLocalization }}</h1>
</div>
<div id="breadcrumb" class="col-lg-auto pl-lg-0">
<abp-breadcrumb />
</div>
<div class="col">
<abp-page-toolbar [record]="data" />
</div>
</div>
<div id="dashboard-id">
<!-- 仪表板内容放置处 -->
</div>
页面组成部分
PageComponent将上述模板划分为三个部分:title(标题)、breadcrumb(面包屑导航)、toolbar(工具栏)。每个部分都可以单独配置。该包还导出了一个枚举,用于描述各个部分:
export enum PageParts {
title = 'PageTitleContainerComponent',
breadcrumb = 'PageBreadcrumbContainerComponent',
toolbar = 'PageToolbarContainerComponent',
}
// 可通过以下方式导入该枚举 -> import { PageParts } from '@abp/ng.components/page';
使用方法
首先,根据使用需求从@abp/ng.components/page导入页面组件。示例如下:
dashboard.component.ts
@Component({
imports: [ PageComponent, ... ]
})
export class DashboardComponent {}
然后将dashboard.component.html的模板修改为:
<abp-page [title]="'::Dashboard' | abpLocalization" [toolbar]="data">
<div id="dashboard-id">
<!-- .... -->
</div>
</abp-page>
输入参数
- title:
string:将在h1.content-header-title中渲染。若不提供,父级div将不会渲染 - breadcrumb:
boolean:决定是否渲染abp-breadcrumb。默认为true - toolbar:
any:将通过record输入参数传递给abp-page-toolbar组件。如果页面不包含abp-page-toolbar,可直接忽略此字段
模板重写
如需替换任何部分的模板,可使用以下子组件。您需要导入这些组件并相应修改HTML模板:
import {
PageComponent,
PageTitleContainerComponent,
PageBreadcrumbContainerComponent,
PageToolbarContainerComponent
} from '@abp/ng.components/page';
@Component({
selector: 'app-sample-component',
template: `
<abp-page>
<abp-page-title-container class="col">
<h2>自定义标题</h2>
</abp-page-title-container>
<abp-page-breacrumb-container class="col">
<my-breadcrumb />
</abp-page-breacrumb-container>
<abp-page-toolbar-container class="col">
<button (click)="doSth()">操作按钮</button>
</abp-page-toolbar-container>
</abp-page>
`,
imports: [
PageComponent,
PageTitleContainerComponent,
PageBreadcrumbContainerComponent,
MyBreadcrumbComponent,
PageToolbarContainerComponent
]
})
export class SampleComponent {}
无需全部提供这些组件,只需使用需要替换的部分即可。这些组件的优先级高于上述声明的输入参数。使用这些组件时,可省略对应的输入参数。
PagePartDirective
Components包提供了一个结构指令,该指令在PageComponent内部使用,也可在外部使用。
PageComponent内部使用该指令的方式如下:
<div class="col-lg-auto pl-lg-0" *abpPagePart="pageParts.breadcrumb">
<abp-breadcrumb />
</div>
该指令还可接收上下文输入参数:
<div class="col" *abpPagePart="pageParts.toolbar; context: toolbarData">
<abp-page-toolbar [record]="toolbarData" />
</div>
其渲染策略可通过Angular的依赖注入系统提供。
该指令期望通过PAGE_RENDER_STRATEGY注入令牌获取一个服务,该服务需实现以下接口:
interface PageRenderStrategy {
shouldRender(type?: string): boolean | Observable<boolean>;
onInit?(type?: string, injector?: Injector, context?: any): void;
onDestroy?(type?: string, injector?: Injector, context?: any): void;
onContextUpdate?(change?: SimpleChange): void;
}
shouldRender(必需):接收名为type的字符串输入,并返回boolean或Observable<boolean>onInit(可选):在指令初始化时调用。将传入三个参数:type:页面部件类型injector:指令的注入器,可用于从指令的DI树中获取任何内容context:初始化阶段可用的任意上下文
onDestroy(可选):在指令销毁时调用。参数与onInit相同onContextUpdate(可选):在上下文更新时调用change:context的变更将通过此方法传递
让我们通过完整示例了解具体用法:
import {
PageModule,
PageRenderStrategy,
PageParts,
PAGE_RENDER_STRATEGY
} from '@abp/ng.components/page';
@Injectable()
export class MyPageRenderStrategy implements PageRenderStrategy {
shouldRender(type: string) {
// 表示除breadcrumb和custom-part外,其他部分都会渲染
return type !== PageParts.breadcrumb && type !== 'custom-part';
}
/**
* shouldRender也可返回Observable<boolean>,
* 这意味着可以在其中使用异步服务
service = inject(SomeAsyncService)
shouldRender(type: string) {
return this.service.checkTypeAsync(type).pipe(map(val => val.isTrue()));
}
*/
onInit(type: string, injector: Injector, context: any) {
// 该方法将在指令的ngOnInit中调用
}
onDestroy(type: string, injector: Injector, context: any) {
// 该方法将在指令的ngOnDestroy中调用
}
onContextUpdate?(change?: SimpleChange) {
// 每次指令内上下文更新时都会调用此方法
}
}
@Component({
selector: 'app-dashboard',
template: `
<abp-page [title]="'::Dashboard' | abpLocalization">
<abp-page-toolbar-container>
<button>新建仪表板</button>
</abp-page-toolbar-container>
<div class="dashboard-content">
<h3 *abpPagePart="'custom-part'"> 内部标题 </h3>
</div>
</abp-page>
`
})
export class DashboardComponent {}
export const appConfig: ApplicationConfig = {
providers: [
{
provide: PAGE_RENDER_STRATEGY,
useClass: MyPageRenderStrategy,
}
],
};
抠丁客


