系列文章
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目
- 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来
- 基于 abp vNext 和 .NET Core 开发博客项目 - 完善与美化,Swagger登场
- 基于 abp vNext 和 .NET Core 开发博客项目 - 数据访问和代码优先
- 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查
- 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
- 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
- 基于 abp vNext 和 .NET Core 开发博客项目 - 接入GitHub,用JWT保护你的API
- 基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据
- 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
- 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
上一篇完成了标签模块和友情链接模块的所有功能,本篇来继续完成博客最后的模块,文章的管理。
文章列表 & 删除
先将分页查询的列表给整出来,这块和首页的分页列表是类似的,就是多了个Id字段。
先添加两条路由规则。
@page "/admin/posts"
@page "/admin/posts/{page:int}"
新建返回数据默认QueryPostForAdminDto.cs
。
//QueryPostForAdminDto.cs
using System.Collections.Generic;
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class QueryPostForAdminDto
{
/// <summary>
/// 年份
/// </summary>
public int Year { get; set; }
/// <summary>
/// Posts
/// </summary>
public IEnumerable<PostBriefForAdminDto> Posts { get; set; }
}
}
//PostBriefForAdminDto.cs
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class PostBriefForAdminDto : PostBriefDto
{
/// <summary>
/// 主键
/// </summary>
public int Id { get; set; }
}
}
然后添加所需的参数:当前页码、限制条数、总页码、文章列表返回数据模型。
/// <summary>
/// 当前页码
/// </summary>
[Parameter]
public int? page { get; set; }
/// <summary>
/// 限制条数
/// </summary>
private int Limit = 15;
/// <summary>
/// 总页码
/// </summary>
private int TotalPage;
/// <summary>
/// 文章列表数据
/// </summary>
private ServiceResult<PagedList<QueryPostForAdminDto>> posts;
然后在初始化函数OnInitializedAsync()
中调用API获取文章数据.
/// <summary>
/// 初始化
/// </summary>
protected override async Task OnInitializedAsync()
{
var token = await Common.GetStorageAsync("token");
Http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
// 设置默认值
page = page.HasValue ? page : 1;
await RenderPage(page);
}
/// <summary>
/// 点击页码重新渲染数据
/// </summary>
/// <param name="page"></param>
/// <returns></returns>
private async Task RenderPage(int? page)
{
// 获取数据
posts = await Http.GetFromJsonAsync<ServiceResult<PagedList<QueryPostForAdminDto>>>($"/blog/admin/posts?page={page}&limit={Limit}");
// 计算总页码
TotalPage = (int)Math.Ceiling((posts.Result.Total / (double)Limit));
}
在初始化中判断page参数,如果没有值给他设置一个默认值1。RenderPage(int? page)
方法是调用API返回数据,并计算出总页码值。
最后在页面上进行数据绑定。
<AdminLayout>
@if (posts == null)
{
<Loading />
}
else
{
<div class="post-wrap archive">
<NavLink style="float:right" href="/admin/post"><h3>