介绍
ABP 是 ASP.NET Boilerplate Project(Asp.net 样板项目)的简称,网址:http://aspnetboilerplate.com/。
ng-alain 是基于 antd 中后台前端解决方案,网址:https://ng-alain.com/。
官方网页下载的项目的angular项目是基于(AdminBSB:https://github.com/gurayyarar/AdminBSBMaterialDesign)
前期准备
在《abp & ng-alain 改造前端 一 —— 项目准备》里,我们将项目已经准备好,接下来我们查看angular项目的运行方式,并将代码迁移至 abpalain中。
在安装完jquery、abp、moment 等依赖包之后,我们需要在typings.d.ts
中定义信息,以便能够在typescript中使用第三方依赖库,添加内容如下
// # 3rd Party Library
// If the library doesn't have typings available at `@types/`,
// you can still use it by manually adding typings for it
///<reference path="../node_modules/@types/jquery/index.d.ts"/>
///<reference path="../node_modules/abp-web-resources/Abp/Framework/scripts/abp.d.ts"/>
///<reference path="../node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.jquery.d.ts"/>
///<reference path="../node_modules/moment/moment.d.ts"/>
///<reference path="../node_modules/@types/moment-timezone/index.d.ts"/>
// Typings reference file, see links for more information
// https://github.com/typings/typings
// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
declare var System: any;
declare var App: any; //Related to Metronic
declare var Layout: any; //Related to Metronic
declare var Push: any;
interface JQuery {
countTo(...any): any;
}
interface JQuery {
sparkline(...any): any;
}
interface JQueryStatic {
AdminBSB: any;
}
为了能够快捷定位到文件,还需要在文件tsconfig.app.json
中添加一下信息
"@abp/*": [ "../node_modules/abp-ng2-module/dist/src/*" ],
"@node_modules/*": [ "../node_modules/*" ],
添加成功后的完整代码如下
完整代码
分析angular项目
-
找到项目入口
main.ts
分析angular入口程序,一般是src下的main.ts文件,代码如下
通过该文件,我们可以看到,在main.ts中,angualr启动RootModule
作为主模块 -
RootModule
root.module.ts文件代码如下
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule, Injector, APP_INITIALIZER, LOCALE_ID } from '@angular/core';
import { AbpModule } from '@abp/abp.module';
import { AbpHttpInterceptor } from '@abp/abpHttpInterceptor';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { SharedModule } from '@shared/shared.module';
import { ServiceProxyModule } from '@shared/service-proxies/service-proxy.module';
import { RootRoutingModule } from './root-routing.module';
import { AppConsts } from '@shared/AppConsts';
import { AppSessionService } from '@shared/session/app-session.service';
import { API_BASE_URL } from '@shared/service-proxies/service-proxies';
import { RootComponent } from './root.component';
import { AppPreBootstrap } from './AppPreBootstrap';
import { ModalModule } from 'ngx-bootstrap';
import { HttpClientModule, HttpResponse } from '@angular/common/http';
export function appInitializerFactory(injector: Injector) {
return () => {
abp.ui.setBusy();
return new Promise<boolean>((resolve, reject) => {
AppPreBootstrap.run(() => {
abp.event.trigger('abp.dynamicScriptsInitialized');
var appSessionService: AppSessionService = injector.get(AppSessionService);
appSessionService.init().then(
(result) => {
abp.ui.clearBusy();
resolve(result);
},
(err) => {
abp.ui.clearBusy();
reject(err);
}
);
});
});
}
}
export function getRemoteServiceBaseUrl(): string {
return AppConsts.remoteServiceBaseUrl;
}
export function getCurrentLanguage(): string {
return abp.localization.currentLanguage.name;
}
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
SharedModule.forRoot(),
ModalModule.forRoot(),
AbpModule,
ServiceProxyModule,
RootRoutingModule,
HttpClientModule
],
declarations: [
RootComponent
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AbpHttpInterceptor, multi: true },
{ provide: API_BASE_URL, useFactory: getRemoteServiceBaseUrl },
{
provide: APP_INITIALIZER,
useFactory: appInitializerFactory,
deps: [Injector],
multi: true
},
{
provide: LOCALE_ID,
useFactory: getCurrentLanguage
}
],
bootstrap: [RootComponent]
})
export class RootModule {
}
我们主要关注以下内容
初始化
初始化方法
上面两个片段说明,angular在启动的时候,提供了一个钩子,以前angular程序在启动之前,能够做自定义的初始化内容。
以上便是整个angular启动的过程,接下来 ,我们将该步骤,迁移到abpalain项目中
复制项目
-
将
AppPreBootstrapAppPreBootstrap.ts
复制到abpalin项目下的src
文件加下
-
将 angular项目下的
src\shared
中的所有文件,复制到abpalain项目下的src\app\shared
中,注意shared.module.ts
文件,由于abpalain在该文件加下已经有一个shared.module.ts
文件,所以需要在复制前修改名称为:abpshared.module.ts
-
修改
abpshared.module.ts
模块名称,将该文件中的导出类,重命名为:AbpSharedModule
修改完毕的代码如下
import { CommonModule } from '@angular/common';
import { NgModule, ModuleWithProviders } from '@angular/core';
import { AbpModule } from '@abp/abp.module';
import { RouterModule } from '@angular/router';
import { AppSessionService } from './session/app-session.service';
import { AppUrlService } from './nav/app-url.service';
import { AppAuthService } from './auth/app-auth.service';
import { AppRouteGuard } from './auth/auth-route-guard';
import { AbpMessage } from './abpmessage/AbpMessage';
@NgModule({
imports: [
CommonModule,
AbpModule,
RouterModule
],
declarations: [
],
exports: [
]
})
export class AbpSharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: AbpSharedModule,
providers: [
AppSessionService,
AppUrlService,
AppAuthService,
AppRouteGuard,
AbpMessage
]
}
}
}
-
修改 app.module.ts 文件,添加abpsharedmodule的依赖,添加abp模块的依赖
app.module.ts
扩展 abplain项目的启动
在app.module.ts
中,查看启动程序的方式
分析可知,该代码将StartupService中的load方法作为启动方法的,那么如何扩展ABP的启动方式呢?
添加Injector依赖
需要改造 StartupServiceFactory方法,添加对Injector
的依赖,见第151行
修改StartupServiceFactory方法,添加Injector,如下代码
export function StartupServiceFactory(
injector: Injector,
startupService: StartupService,
): Function
启动ABP
查看startupService.load()方式返回结果的格式是:Promise,这也意味着,我们可以使用一下方式来启动
修改网络访问地址
ng-alain中,使用了两个http拦截器:SimpleInterceptor
和DefaultInterceptor
,需要将这两个拦截器注释,添加ABP的拦截器代码
修改完http拦截器之后,还需要定义API访问的BaseUrl,内容如下
修改完毕后的代码如下:
运行
使用命令: npm start
,如果浏览器出现如下界面表示运行成功
F12 查看网路请求
网络请求
通过网络请求,可以看到,abpalain项目已经在程序启动的时候进行abp后端接口的访问
弹出框提示和提醒
得益于ABP作者的高度可扩展的思想,我们可以在不依赖notify
等组件的情况下,将弹出框提示和提醒,自定义 扩展为 antd样式
在shared中新建AbpMessage类,代码如下
import { Injectable } from '@angular/core';
import { NzModalService ,NzNotificationService ,NzMessageService } from 'ng-zorro-antd';
import { reverse } from 'dns';
import { reject } from 'q';
@Injectable()
export class AbpMessage {
constructor(private modalService: NzModalService,
private messageService:NzMessageService) {
}
init(){
this.initMessage();
this.initNotify();
}
initNotify(){
abp.notify.info=(message: string, title?: string)=>{
this.messageService.create('info', message);
}
abp.notify.success=(message: string, title?: string)=>{
this.messageService.create('success', message);
}
abp.notify.warn=(message: string, title?: string)=>{
this.messageService.create('warn', message);
}
abp.notify.error=(message: string, title?: string)=>{
this.messageService.create('error', message);
}
}
initMessage(){
abp.message.info = (message, title)=>{
var dispalyTitle = title==null?message:title;
this.modalService.info({
nzTitle: dispalyTitle,
nzContent: message,
nzOnOk: () => console.log('Info OK')
});
};
abp.message.success = (message, title)=>{
var dispalyTitle = title==null?message:title;
this.modalService.success({
nzTitle: dispalyTitle,
nzContent: message
});
};
abp.message.warn = (message, title)=>{
var dispalyTitle = title==null?message:title;
this.modalService.warning({
nzTitle: dispalyTitle,
nzContent: message
});
};
abp.message.error = (message, title)=>{
var dispalyTitle = title==null?message:title;
this.modalService.error({
nzTitle: dispalyTitle,
nzContent: message
});
};
abp.message.confirm=(message)=>{
return new Promise<boolean>((reverse,reject)=>{
this.modalService.confirm({
// nzTitle: '<i>Do you Want to delete these items?</i>',
nzContent: message,
nzOnOk: () => reverse(true),
nzOnCancel: () => reverse(false)
});
})
}
}
}
代码中的核心是替换abp框架定义的函数
测试弹出框提示和提醒
在程序启动的时候,需要添加AbpMessage初始化的代码
image.png在添加链式调用,以便测试AbpMessage是否生效
运行结果如下
经过上面的改造,已经成功替换 abp中的弹出框提示和提醒功能,在后面的模块中,可以直接使用
abp.message
和 abp.notify
总结
该篇主要分享了如何参考angular项目改造ng-alain项目启动的过程,经过这篇文章,我们已经初步掌握了abp前端项目的启动流程,接下来进入页面改造工作。
网友评论