使用.net core ABP和Angular模板构建博客管理系统(实现博客列表页面)

返回目录

创建服务

新建一个服务文件

ng g service blog/note-service

我们可以参考shared\service-proxies\service-proxies.ts文件来写我们的服务文件,这是模板提供的,看最上面的介绍,说的好像是用NSwag自动生成的,博主现在是用不了这个工具,有办法用的请指教。

image.png
service-proxies.ts

先把后台Api地址拷过来吧

// api域名
const ApiHost = 'http://localhost:21021';
// api地址
const NoteApiUrls = {
    Create: ApiHost + '/api/services/app/NoteAppServer/Create',
    PublicNote: ApiHost + '/api/services/app/NoteAppServer/PublicNote',
    Update: ApiHost + '/api/services/app/NoteAppServer/Update',
    GetAll: ApiHost + '/api/services/app/NoteAppServer/GetAll',
    GetNote: ApiHost +  '/api/services/app/NoteAppServer/GetNote',
    Delete:  ApiHost + '/api/services/app/NoteAppServer/Delete'
};

现在使用typeScript来写代码,创建服务基本和我们写后台的service差不多了。现在我们来定义数据的载体DTO,基本和后台一样。所以这个能用代码生成器生成也是很能理解的。

export class PageOfNoteDto {
    totalCount: number;
    items: NoteDto[];
}

export class CreateNoteDto {
    textType: number
}
// 首字母必须小写
export class NoteDto {
    title: string;
    creationTime: string;
    id: number;
    like: number;
    collect: number;
    scan: number;
    isPublic: boolean;
}

先照着写一个方法吧

import {SwaggerException} from '@shared/service-proxies/service-proxies';

export class NoteServiceService {
    protected jsonParseReviver: (key: string, value: any) => any = undefined;

    constructor(private http: Http) {

    }
    // 对于get请求我们要把参数拼接到url上面,这是api的特殊地方
    GetAll(MaxResultCount = 20, SkipCount = 0, key = ''): Observable<PageOfNoteDto> {
        let url_ = NoteApiUrls.GetAll + '?';
        url_ += 'SkipCount=' + encodeURIComponent('' + SkipCount) + '&';
        url_ += 'MaxResultCount=' + encodeURIComponent('' + MaxResultCount) + '&';
        url_ += 'key=' + encodeURIComponent('' + key);
        url_ = url_.replace(/[?&]$/, '');

        const options_ = {
            method: 'get',
            headers: new Headers({
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            })
        };
        return this.http.request(url_, options_).flatMap((response_) => {
            return this.processGetAll(response_);
        }).catch((response_: any) => {
            if (response_ instanceof Response) {
                try {
                    return this.processGetAll(response_);
                } catch (e) {
                    return <Observable<PageOfNoteDto>><any>Observable.throw(e);
                }
            } else
                return <Observable<PageOfNoteDto>><any>Observable.throw(response_);
        });
    }

    protected processGetAll(response: Response): Observable<PageOfNoteDto> {
        const status = response.status;

        const _headers: any = response.headers ? response.headers.toJSON() : {};
        if (status === 200) {
            const _responseText = response.text();
            let result200: any = null;
            const resultData200 = _responseText === '' ? null : JSON.parse(_responseText, this.jsonParseReviver);
            result200 = resultData200 ? resultData200 as PageOfNoteDto : new PageOfNoteDto();
            console.log(_responseText);
            console.log(result200);
            console.log(resultData200);
            return Observable.of(result200);
        } else if (status === 401) {
            const _responseText = response.text();
            return this.throwException('服务器错误', status, _responseText, _headers);
        } else if (status === 403) {
            const _responseText = response.text();
            return this.throwException('服务器错误', status, _responseText, _headers);
        } else if (status !== 200 && status !== 204) {
            const _responseText = response.text();
            return this.throwException('意料之外的出现', status, _responseText, _headers);
        }
        return Observable.of<PageOfNoteDto>(<any>null);
    }

    protected throwException(message: string, status: number, response: string,
                             headers: { [key: string]: any; }, result?: any): Observable<any> {
        if (result !== null && result !== undefined) {
            return Observable.throw(result);
        } else {
            return Observable.throw(new SwaggerException(message, status, response, headers, null));
        }
    }
}

使用服务

在我们的note.component.ts中引入来看看我们服务对不对。

import { Component, OnInit, Injector } from '@angular/core';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import { PagedListingComponentBase, PagedRequestDto } from 'shared/paged-listing-component-base';
import {NoteDto, NoteServiceService, PageOfNoteDto} from '@app/blog/note-service.service'

@Component({
  selector: 'app-note',
  templateUrl: './note.component.html',
  styleUrls: ['./note.component.css'],
    animations: [appModuleAnimation()]
})
export class NoteComponent extends PagedListingComponentBase<NoteDto> {

  constructor(private noteService: NoteServiceService,
              injector: Injector) {
      super(injector);
  }

    protected list(request: PagedRequestDto, pageNumber: number, finishedCallback: Function): void {
        this.noteService.GetAll(20, 0 )
            .finally(() => {
                finishedCallback();
            })
            .subscribe((result: PageOfNoteDto) => {
                console.log(result);
            });
    }

    protected delete(user: NoteDto): void {

    }

}
出错了,服务没有提供

是因为在app.module.ts里面没有引入的原因:

import {NoteServiceService} from '@app/blog/note-service.service'
    providers: [
        NoteServiceService
    ]

再试一下呢。

没有权限啊~~~

在角色管理页面给当前用户的角色添加notes这个权限。因为我们后台添加了访问权限的

给当前用户添加权限
控制台没有报错,还打印出来一些东西,貌似就是我们后台传来的数据

看来通信正常,可以继续完善页面了。

 notes: NoteDto[]; // 文章列表
    protected list(request: PagedRequestDto, pageNumber: number, finishedCallback: Function): void {
        this.noteService.GetAll(request.maxResultCount, request.skipCount)
            .finally(() => {
                finishedCallback();
            })
            .subscribe((result: PageOfNoteDto) => {
                this.notes = result.items;
                this.showPaging(result, pageNumber);
            });
    }

把用户页面(users.component.html)的内容拷贝过来,放在我们note.component.html文件里,进行如下修改。

<div class="row clearfix" [@routerTransition]>
    <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
        <div class="card main-content">
            <div class="header">
                <h2>
                    文章列表
                </h2>
                <ul class="header-dropdown m-r--5">
                    <i class="fa fa-spin fa-spinner" *ngIf="isTableLoading"></i>
                    <li class="dropdown">
                        <a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                            <i class="material-icons">more_vert</i>
                        </a>
                        <ul class="dropdown-menu pull-right">
                            <li><a href="javascript:void(0);" class=" waves-effect waves-block()" (click)="refresh();"><i class="material-icons">refresh</i> {{l('Refresh')}}</a></li>
                        </ul>
                    </li>
                </ul>
            </div>
            <div class="body table-responsive">

                <!-- ******************************************************** -->
                <table class="table table-hover table-striped">
                    <thead>
                    <tr>
                        <th>文章标题</th>
                        <th>阅读次数</th>
                        <th>点赞次数</th>
                        <th>
                            <div style="text-align:center">是否发布</div>
                        </th>
                        <th>创建时间</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr *ngFor="let note of notes | paginate: { id: 'server', itemsPerPage: pageSize, currentPage: pageNumber, totalItems: totalItems }">
                        <td>{{note.title}}</td>
                        <td>{{note.scan}}</td>
                        <td>{{note.like}}</td>
                        <td align="center">
                            <i class="material-icons" *ngIf="note.isPublic" style="color:green;">check_box</i>
                            <i class="material-icons" *ngIf="!note.isPublic" style="color:red;">indeterminate_check_box</i>
                        </td>
                        <td>{{note.creationTime}}</td>
                        <td class="dropdown">
                            <a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                                <i class="material-icons">menu</i>
                            </a>
                            <ul class="dropdown-menu pull-right">
                                <li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="editUser(note)"><i class="material-icons">create</i>编辑}</a></li>
                                <li><a href="javascript:void(0);" class="waves-effect waves-block" (click)="delete(note)"><i class="material-icons">delete_sweep</i>修改</a></li>
                            </ul>
                        </td>
                    </tr>
                    </tbody>
                </table>
                <!-- ******************************************************** -->

                <div class="text-align: center;" *ngIf="totalItems > pageSize">
                    <pagination-controls (pageChange)="getDataPage($event)" id="server"></pagination-controls>
                </div>
                <button type="button" data-toggle="modal" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" (click)="createUser()">
                    <i class="material-icons">add</i>
                </button>
            </div>
        </div>
    </div>
</div>

数据库里只有两条测试数据

思考

  • 我们继承了PagedListingComponentBase类,可以仔细看看这个类的定义,学习下高级架构师在封装这些公用基类时都考虑了些什么,我们该如何来扩展。
  • {l('Users')}是什么意思,l是本地化的意思,可以根据我们界面右上角的语言选择来自动显示不同的语言文字。后面将要学习下如何使用,这显得我们的软件更加的国际化。
  • 既然我们用不了代码生成器,那么完全照着抄写service是不是很累? 我们可以自自己写一个dto的代码生成器,至于service我们可以抽象出一个基类来嘛。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容