• abp.zero 9.0框架的前端Angular使用说明


    abp.zero 9.0框架的前端Angular使用说明

    摘要

    某宝可自行购买 abp.zero 框架,本文相关的Abp Zero Angular 培训 B站视频有需要的可前往B站观看。

    1 部署及启动

    1.1 依赖包安装

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

    备注:已经安装的可忽略此项,国外资源不好访问问题,自己用国内淘宝或者其他第三方镜像解决。

    1.2 使用yarn安装依赖包

    yarn

    1.3 启动前端项目运行

    yarn start

    编译完后,可在浏览器中打开:http://localhost:4200,默认账号:admin/123qwe

    2 代码使用

    2.1 配置路由

    src/shared/layout/nav/
    找到配置路由服务app-navigation.server.ts
    添加新的路由

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

    2.2 对路由注入逻辑服务

    我这里假设将Fsu管理组件注入到main文件夹下,main-routing.module.ts文件

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

    此时编译会报错,因为并无fsuManagerComponent组件服务,继续往下添加,另外组件的命名方式(FsuManagerComponent)必须是
    Pascal命名方式,首字母需要大写否则会报错。

    2.3 编写组件代码

    2.3.1 创建组件文件夹fsuDevice

    创建组件服务文件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);
        }
    }
    

    2.3.2 fsuManager组件html文件

    <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>
    

    2.3.3 声明服务

    在main.module.ts中声明fsuManager服务组件。

        declarations: [
            DashboardComponent,
            FsuManagerComponent
        ],
    

    3.后台接口地址配置

    3.1 调试开发远程接口地址配置

    appconfig.json
    文件位置:src/assets/

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

    3.2 生产环境远程地址配置

    appconfig.production.json
    文件位置:src/assets/

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

    4 后台接口服务的调用

    4.1 调用形式

    使用nswag扫描后台新增接口,生成代理服务,此服务类同时会提供Dto模型(实体或者实体集合),
    非常方便前端人员编码,根据接口文档来对后台服务下的增删改查接口进行调用。

    4.2 配置nswag扫描的后台服务地址nswag/service.config.nswag文档,修改内容如下:

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

    4.3 windows调用nswag

    进入nswag文件夹调用refresh.bat批处理文件

    ./refresh.bat
    

    4.4 macOs调用nswag

    进入nswag文件夹调用refresh.sh批处理文件

    ./refresh.sh
    

    备注:该脚本是自己编写,有需要读者可提供。

    4.5 生成的后台接口服务类及其实体类

    位置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;
    }
    

    4.6 将生成的代理服务注入到module中去

    找到service-proxy.module.ts文件,嫁给你FsuManager代理服务注入到NgModule中去。

    ApiServiceProxies.FsuManagerServiceProxy,
    

    4.7 创建对应的业务文件

    创建如下业务文件.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

  • 相关阅读:
    转换流--OutputStreamWriter类与InputStreamReader类
    Android getResources的作用和须要注意点
    sqlit使用要点之引入libsqlite3.dylib
    C语言文件操作之fgets()
    5款伊思儷超媒體繁体游戏 中文简体补丁
    memcpy的使用方法总结
    开发人员改变世界的初心
    expect
    HDU 1061 N^N (n的n次方的最后一位)
    linux杂谈(二十):apache服务配置
  • 原文地址:https://www.cnblogs.com/JerryMouseLi/p/14150486.html
Copyright © 2020-2023  润新知