abp & ng-alain 改造前端 二 —— 初始化运行


介绍

ABP 是 ASP.NET Boilerplate Project(Asp.net 样板项目)的简称,网址:http://aspnetboilerplate.com/。
ng-alain 是基于 antd 中后台前端解决方案,网址:https://ng-alain.com/。
官方网页下载的项目的angular项目是基于(AdminBSB:https://github.com/gurayyarar/AdminBSBMaterialDesign)

  1. 目录:https://www.jianshu.com/p/589af988637c
  2. 源代码:https://github.com/ZhaoRd/abp-alain

前期准备

在《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
///
///
///
///
///

// 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/*" ],

添加成功后的完整代码如下


abp & ng-alain 改造前端 二 —— 初始化运行_第1张图片
完整代码

分析angular项目

  1. 找到项目入口
    分析angular入口程序,一般是src下的main.ts文件,代码如下

    abp & ng-alain 改造前端 二 —— 初始化运行_第2张图片
    main.ts

    通过该文件,我们可以看到,在main.ts中,angualr启动RootModule作为主模块

  2. 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((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 {

}

我们主要关注以下内容


abp & ng-alain 改造前端 二 —— 初始化运行_第3张图片
初始化

abp & ng-alain 改造前端 二 —— 初始化运行_第4张图片
初始化方法

上面两个片段说明,angular在启动的时候,提供了一个钩子,以前angular程序在启动之前,能够做自定义的初始化内容。

以上便是整个angular启动的过程,接下来 ,我们将该步骤,迁移到abpalain项目中


复制项目

  1. AppPreBootstrap.ts复制到abpalin项目下的src文件加下

    abp & ng-alain 改造前端 二 —— 初始化运行_第5张图片
    AppPreBootstrap

  2. 将 angular项目下的 src\shared中的所有文件,复制到abpalain项目下的src\app\shared中,注意 shared.module.ts 文件,由于abpalain在该文件加下已经有一个shared.module.ts 文件,所以需要在复制前修改名称为:abpshared.module.ts

  3. 修改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
            ]
        }
    }
}

  1. 修改 app.module.ts 文件,添加abpsharedmodule的依赖,添加abp模块的依赖


    abp & ng-alain 改造前端 二 —— 初始化运行_第6张图片
    app.module.ts

扩展 abplain项目的启动

app.module.ts中,查看启动程序的方式

abp & ng-alain 改造前端 二 —— 初始化运行_第7张图片
启动方式

abp & ng-alain 改造前端 二 —— 初始化运行_第8张图片
启动方法

分析可知,该代码将StartupService中的load方法作为启动方法的,那么如何扩展ABP的启动方式呢?

添加Injector依赖

需要改造 StartupServiceFactory方法,添加对Injector的依赖,见第151行

image.png

修改StartupServiceFactory方法,添加Injector,如下代码

export function StartupServiceFactory(
  injector: Injector,
  startupService: StartupService,
): Function 

启动ABP

查看startupService.load()方式返回结果的格式是:Promise,这也意味着,我们可以使用一下方式来启动


abp & ng-alain 改造前端 二 —— 初始化运行_第9张图片

修改网络访问地址

ng-alain中,使用了两个http拦截器:SimpleInterceptorDefaultInterceptor,需要将这两个拦截器注释,添加ABP的拦截器代码


修改完http拦截器之后,还需要定义API访问的BaseUrl,内容如下


abp & ng-alain 改造前端 二 —— 初始化运行_第10张图片

修改完毕后的代码如下:


abp & ng-alain 改造前端 二 —— 初始化运行_第11张图片

运行

使用命令: npm start,如果浏览器出现如下界面表示运行成功

abp & ng-alain 改造前端 二 —— 初始化运行_第12张图片
运行界面

F12 查看网路请求


abp & ng-alain 改造前端 二 —— 初始化运行_第13张图片
网络请求

abp & ng-alain 改造前端 二 —— 初始化运行_第14张图片

通过网络请求,可以看到,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((reverse,reject)=>{

                this.modalService.confirm({
                    // nzTitle: 'Do you Want to delete these items?',
                     nzContent: message,
                     nzOnOk: () => reverse(true),
                     nzOnCancel: () => reverse(false)
                   });

            })

          }
        
    }

}

代码中的核心是替换abp框架定义的函数



abp & ng-alain 改造前端 二 —— 初始化运行_第15张图片

测试弹出框提示和提醒

在程序启动的时候,需要添加AbpMessage初始化的代码

abp & ng-alain 改造前端 二 —— 初始化运行_第16张图片
image.png

在添加链式调用,以便测试AbpMessage是否生效

运行结果如下

abp & ng-alain 改造前端 二 —— 初始化运行_第17张图片

经过上面的改造,已经成功替换 abp中的弹出框提示和提醒功能,在后面的模块中,可以直接使用 abp.messageabp.notify


总结

该篇主要分享了如何参考angular项目改造ng-alain项目启动的过程,经过这篇文章,我们已经初步掌握了abp前端项目的启动流程,接下来进入页面改造工作。


我的公众号

abp & ng-alain 改造前端 二 —— 初始化运行_第18张图片
我的公众号

源代码

源代码:https://github.com/ZhaoRd/abp-alain

你可能感兴趣的:(abp & ng-alain 改造前端 二 —— 初始化运行)