天天看點

abp.zero 9.0架構的前端Angular使用說明

abp.zero 9.0架構的前端Angular使用說明

目錄

    • 摘要
  • 1 部署及啟動
    • 1.1 依賴包安裝
    • 1.2 使用yarn安裝依賴包
    • 1.3 啟動前端項目運作
  • 2 代碼使用
    • 2.1 配置路由
    • 2.2 對路由注入邏輯服務
    • 2.3 編寫元件代碼
      • 2.3.1 建立元件檔案夾fsuDevice
      • 2.3.2 fsuManager元件html檔案
      • 2.3.3 聲明服務
  • 3.背景接口位址配置
    • 3.1 調試開發遠端接口位址配置
    • 3.2 生産環境遠端位址配置
  • 4 背景接口服務的調用
    • 4.1 調用形式
    • 4.2 配置nswag掃描的背景服務位址nswag/service.config.nswag文檔,修改内容如下:
    • 4.3 windows調用nswag
    • 4.4 macOs調用nswag
    • 4.5 生成的背景接口服務類及其實體類
    • 4.6 将生成的代理服務注入到module中去
    • 4.7 建立對應的業務檔案

某寶可自行購買 abp.zero 架構,本文相關的Abp Zero Angular 教育訓練 B站視訊有需要的可前往B站觀看。

  • 安裝nodejs(自包含npm包管理);
  • yarn包管理;

備注:已經安裝的可忽略此項,國外資源不好通路問題,自己用國内淘寶或者其他第三方鏡像解決。

yarn

yarn start

編譯完後,可在浏覽器中打開:http://localhost:4200,預設賬号:admin/123qwe

src/shared/layout/nav/

找到配置路由服務app-navigation.server.ts

添加新的路由

new AppMenuItem('Fsu管理', null, 'flaticon-line-graph', '/app/main/fsuManager'),
           

我這裡假設将Fsu管理元件注入到main檔案夾下,main-routing.module.ts檔案

{ path: 'fsuManager', component: FsuManagerComponent },
           

此時編譯會報錯,因為并無fsuManagerComponent元件服務,繼續往下添加,另外元件的命名方式(FsuManagerComponent)必須是

Pascal命名方式,首字母需要大寫否則會報錯。

建立元件服務檔案fsuManager.component.ts, fsuManager.component.html

css檔案的引入與html檔案引入類似,舉例 styleUrls: ['./users.component.less'],

自行完善

各元件含義自行去網上查詢學習。主要介紹AppComponentBase,架構的基類,

目的是為了更友善的生成各種業務類,業務類直接繼承此類即可。

import { Component, Injector } from '@angular/core';
import { AppComponentBase } from '@shared/common/app-component-base';
import { appModuleAnimation } from '@shared/animations/routerTransition';

@Component({
    templateUrl: './fsuManager.component.html',
    animations: [appModuleAnimation()]
})
export class FsuManagerComponent extends AppComponentBase {
    constructor(injector: Injector) {
        super(injector);
    }
}
           

<div [@routerTransition]>
    <div class="modal-content">
    <div class="m-portlet m-portlet--mobile">
        <div class="m=portlet_body">
            <p>welcome to Fsumanager!</p>
        </div>
    </div>
    </div>
</div>
           

在main.module.ts中聲明fsuManager服務元件。

declarations: [
        DashboardComponent,
        FsuManagerComponent
    ],
           

appconfig.json

檔案位置:src/assets/

"remoteServiceBaseUrl": "http://localhost:21021",
           

appconfig.production.json

"remoteServiceBaseUrl": "https:www.daxxxop.tech/proxyForApi",
           

使用nswag掃描背景新增接口,生成代理服務,此服務類同時會提供Dto模型(實體或者實體集合),

非常友善前端人員編碼,根據接口文檔來對背景服務下的增删改查接口進行調用。

"url": "http://localhost:21021/swagger/v1/swagger.json",
           

進入nswag檔案夾調用refresh.bat批處理檔案

./refresh.bat
           

進入nswag檔案夾調用refresh.sh批處理檔案

./refresh.sh
           

備注:該腳本是自己編寫,有需要讀者可提供。

位置src/shared/service-proxies.ts

這裡架構使用了代理設計模式,思考下,代理設計模式的目的??

自動生成了FsuManagerServiceProxy代理類,裡面有getFsu方法可傳入

filter過濾字段;注冊到Ngmodule裡,其他頁面即可調用。

這裡pipe是rxjs裡的管道概念,可在管道裡對資料做延時或者資料變換。

@Injectable()
export class FsuManagerServiceProxy {
    private http: HttpClient;
    private baseUrl: string;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

    constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) {
        this.http = http;
        this.baseUrl = baseUrl ? baseUrl : "";
    }

    /**
     * @param filter (optional) 
     * @return Success
     */
    getFsu(filter: string | null | undefined): Observable<ListResultDtoOfFsuListDto> {
        let url_ = this.baseUrl + "/api/services/app/FsuManager/GetFsu?";
        if (filter !== undefined)
            url_ += "Filter=" + encodeURIComponent("" + filter) + "&"; 
        url_ = url_.replace(/[?&]$/, "");

        let options_ : any = {
            observe: "response",
            responseType: "blob",			
            headers: new HttpHeaders({
                "Accept": "text/plain"
            })
        };

        return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => {
            return this.processGetFsu(response_);
        })).pipe(_observableCatch((response_: any) => {
            if (response_ instanceof HttpResponseBase) {
                try {
                    return this.processGetFsu(<any>response_);
                } catch (e) {
                    return <Observable<ListResultDtoOfFsuListDto>><any>_observableThrow(e);
                }
            } else
                return <Observable<ListResultDtoOfFsuListDto>><any>_observableThrow(response_);
        }));
    }

    protected processGetFsu(response: HttpResponseBase): Observable<ListResultDtoOfFsuListDto> {
        const status = response.status;
        const responseBlob = 
            response instanceof HttpResponse ? response.body : 
            (<any>response).error instanceof Blob ? (<any>response).error : undefined;

        let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
        if (status === 200) {
            return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
            let result200: any = null;
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = ListResultDtoOfFsuListDto.fromJS(resultData200);
            return _observableOf(result200);
            }));
        } else if (status !== 200 && status !== 204) {
            return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
            }));
        }
        return _observableOf<ListResultDtoOfFsuListDto>(<any>null);
    }
           

以及掃描出背景FsuListDto及其接口的形式,增加了json序列化與反序列化的方法;

export class FsuListDto implements IFsuListDto {
    fsuName!: string | undefined;
    id!: number;

    constructor(data?: IFsuListDto) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(_data?: any) {
        if (_data) {
            this.fsuName = _data["fsuName"];
            this.id = _data["id"];
        }
    }

    static fromJS(data: any): FsuListDto {
        data = typeof data === 'object' ? data : {};
        let result = new FsuListDto();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        data["fsuName"] = this.fsuName;
        data["id"] = this.id;
        return data; 
    }
}
           

接口形式如下:

export interface IFsuListDto {
    fsuName: string | undefined;
    id: number;
}
           

将其傳回形式封裝程item

export class ListResultDtoOfFsuListDto implements IListResultDtoOfFsuListDto {
    items!: FsuListDto[] | undefined;

    constructor(data?: IListResultDtoOfFsuListDto) {
        if (data) {
            for (var property in data) {
                if (data.hasOwnProperty(property))
                    (<any>this)[property] = (<any>data)[property];
            }
        }
    }

    init(_data?: any) {
        if (_data) {
            if (Array.isArray(_data["items"])) {
                this.items = [] as any;
                for (let item of _data["items"])
                    this.items!.push(FsuListDto.fromJS(item));
            }
        }
    }

    static fromJS(data: any): ListResultDtoOfFsuListDto {
        data = typeof data === 'object' ? data : {};
        let result = new ListResultDtoOfFsuListDto();
        result.init(data);
        return result;
    }

    toJSON(data?: any) {
        data = typeof data === 'object' ? data : {};
        if (Array.isArray(this.items)) {
            data["items"] = [];
            for (let item of this.items)
                data["items"].push(item.toJSON());
        }
        return data; 
    }
}

export interface IListResultDtoOfFsuListDto {
    items: FsuListDto[] | undefined;
}
           

找到service-proxy.module.ts檔案,嫁給你FsuManager代理服務注入到NgModule中去。

ApiServiceProxies.FsuManagerServiceProxy,
           

建立如下業務檔案.ts,頁面檔案.html,當然有需要的話可以增加.css。

本文不對.css多做說明,自行學習。

fsuManager.component.ts
fsuManager.component.html
           

fsuManager.component.ts代碼如下

import {Component, Injector, OnInit} from '@angular/core';
import { AppComponentBase } from '@shared/common/app-component-base';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import {FsuListDto, FsuManagerServiceProxy} from '@shared/service-proxies/service-proxies';
import {ThemesLayoutBaseComponent} from '@app/shared/layout/themes/themes-layout-base.component';

//注冊了元件模闆的位置
@Component({
    templateUrl: './fsuManager.component.html',
    animations: [appModuleAnimation()]
})
export class FsuManagerComponent extends AppComponentBase  implements OnInit {
    fsuList: FsuListDto[] = [];
    filter: string = '';
    constructor(injector: Injector,
                private _fsuManagerService: FsuManagerServiceProxy) {
        super(injector);
    }
    ngOnInit(): void {
        this.getFsu();
    }
    getFsu(): void {
        this._fsuManagerService.getFsu(this.filter).subscribe((result) => {
            this.fsuList = result.items;
            }
        );
    }
}
           

subscribe rxjs 響應式程式設計中的釋出訂閱模式;

RxJS: 簡單入門

Rxjs_觀察者模式和釋出訂閱模式

*.html檔案中主要用了ngFor,與vue中的v-for基本類似。另外需要明确掉用的UI元件,找到其官網位址,

沒用一個元件要看其說明,可能是英文網站,學會用谷歌翻譯。

<div [@routerTransition]>
    <div class="row margin-bottom-5">
        <div class="col-xs-12">
            <div class="page-head">
                <div class="page-title">
                    <h1>
                        <span>{{l("Fsu清單")}}</span>
                    </h1>
                </div>
            </div>
        </div>
    </div>

    <div class="portlet light margin-bottom-0">
        <div class="portlet-body">

            <h3>{{l("Fsu Manager")}}</h3>

            <div class="list-group">
                <a *ngFor="let fsu of fsuList" href="javascript:;" class="list-group-item">
                    <h4 class="list-group-item-heading">
                        {{fsu.id + ' ' + fsu.fsuName}}
                    </h4>
                    <p class="list-group-item-text">
                        {{fsu.fsuName}}
                    </p>
                </a>
            </div>

        </div>
    </div>
</div>
           

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結和本聲明。 本文連結:https://www.cnblogs.com/JerryMouseLi/p/14150486.html

The Sky is the limit.