基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
系列文章
- 基于 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 实战系列(三)
上一篇完成了博客的分页查询文章列表页面的数据绑定和分页功能,本篇将继续完成剩下的几个页面。
在开始主题之前重新解决上一篇的最后一个问题,当点击了头部组件的/posts
链接时直接强制刷新了页面,经过查看文档和实践有了更好的解决方案。
先将头部组件Header.razor
中的NavLink
恢复成<NavLink class="menu-item" href="posts">Posts</NavLink>
,不需要点击事件了。
然后在Posts.razor
中添加生命周期函数OnParametersSetAsync()
,在初始化完成后执行。
/// <summary>
/// 初始化完成后执行
/// </summary>
/// <returns></returns>
protected override async Task OnParametersSetAsync()
{
if (!page.HasValue)
{
page = 1;
await RenderPage(page);
}
}
判断当前page参数是否有值,有值的话说明请求肯定是来自于翻页,当page没有值的时候就说明是头部的菜单点进来的。那么此时给page赋值为1,调用API加载数据即可。
分类列表
Categories.razor
是分类列表页面,上篇文章已经实现了从API获取数据的方法,所以这里就很简单了,指定接受类型,然后在生命周期初始化OnInitializedAsync()
中去获取数据。
@code{
/// <summary>
/// categories
/// </summary>
private ServiceResult<IEnumerable<QueryCategoryDto>> categories;
/// <summary>
/// 初始化
/// </summary>
protected override async Task OnInitializedAsync()
{
// 获取数据
categories = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryCategoryDto>>>($"/blog/categories");
}
}
当获取到数据的时候进行绑定,没有数据的时候还是显示加载中的组件<Loading />
让他转圈圈。
@if (categories == null)
{
<Loading />
}
else
{
<div class="container">
<div class="post-wrap categories">
<h2 class="post-title">- Categories -</h2>
<div class="categories-card">
@if (categories.Success && categories.Result.Any())
{
@foreach (var item in categories.Result)
{
<div class="card-item">
<div class="categories">
<a href="/category/@item.DisplayName/">
<h3>
<i class="iconfont iconcode" style="padding-right:3px"></i>
@item.CategoryName
</h3>
<small>(@item.Count)</small>
</a>
</div>
</div>
}
}
else
{
<ErrorTip />
}
</div>
</div>
</div>
}
直接循环返回的数据列表categories.Result
,绑定数据就好,当获取失败或者没有返回数据的时候显示错误提示组件<ErrorTip />
标签列表
Categories.razor
是标签列表页面,和分类列表HTML结构差不多一样的,除了返回类型和接口地址不一样,将上面代码复制过来改改即可。
@code{
/// <summary>
/// tags
/// </summary>
private ServiceResult<IEnumerable<QueryTagDto>> tags;
/// <summary>
/// 初始化
/// </summary>
protected override async Task OnInitializedAsync()
{
// 获取数据
tags = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryTagDto>>>($"/blog/tags");
}
}
@if (tags == null)
{
<Loading />
}
else
{
<div class="container">
<div class="post-wrap tags">
<h2 class="post-title">- Tags -</h2>
<div class="tag-cloud-tags">
@if (tags.Success && tags.Result.Any())
{
@foreach (var item in tags.Result)
{
<a href="/tag/@item.DisplayName/">@item.TagName<small>(@item.Count)</small></a>
}
}
else
{
<ErrorTip />
}
</div>
</div>
</div>
}
友链列表
FriendLinks.razor
是友情链接列表页面,实现方式和上面两个套路一模一样。
@code {
/// <summary>
/// friendlinks
/// </summary>
private ServiceResult<IEnumerable<FriendLinkDto>> friendlinks;
/// <summary>
/// 初始化
/// </summary>
protected override async Task OnInitializedAsync()
{
// 获取数据
friendlinks = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<FriendLinkDto>>>($"/blog/friendlinks");
}
}
@if (friendlinks == null)
{
<Loading />
}
else
{
<div class="container">
<div class="post-wrap categories">
<h2 class="post-title">- FriendLinks -</h2>
<div class="categories-card">
@if (friendlinks.Success && friendlinks.Result.Any())
{
@foreach (var item in friendlinks.Result)
{
<div class="card-item">
<div class="categories">
<a target="_blank" href="@item.LinkUrl">
<h3>@item.Title</h3>
</a>
</div>
</div>
}
}
else
{
<ErrorTip />
}
</div>
</div>
</div>
}
文章列表(分类)
Posts.Category.razor
是根据分类查询文章列表页面,他接受一个参数name,我们要根据name去API查询数据然后绑定页面即可。
这里的参数name实际上就是从标签列表传递过来的DisplayName
的值,它是一个比较友好的名称,我们还要通过这个值去查询真正的分类名称进行展示,所以这里需要调用两个API,这点在设计API的时候没有考虑好,我们其实可以将这两个API合并变成一个,后续再进行优化吧,这里就请求两次。
添加两个接收参数:分类名称和返回的文章列表数据。
/// <summary>
/// 分类名称
/// </summary>
private string categoryName;
/// <summary>
/// 文章列表数据
/// </summary>
private ServiceResult<IEnumerable<QueryPostDto>> posts;
然后在OnInitializedAsync()
初始化方法中调用API获取数据,赋值给变量。
/// <summary>
/// 初始化
/// </summary>
protected override async Task OnInitializedAsync()
{
// TODO:获取数据,可以在API中合并这两个请求。
var category = await Http.GetFromJsonAsync<ServiceResult<string>>($"/blog/category?name={name}");
posts = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryPostDto>>>($"/blog/posts/category?name={name}");
if (category.Success)
{
categoryName = category.Result;
}
}
有了数据,直接在页面上进行循环绑定。
@if (posts == null)
{
<Loading />
}
else
{
<div class="container">
<div class="post-wrap tags">
@if (categoryName != null)
{
<h2 class="post-title">- Category · @categoryName -</h2>
}
</div>
<div class="post-wrap archive">
@if (posts.Success && posts.Result.Any())
{
@foreach (var item in posts.Result)
{
<h3>@item.Year</h3>
@foreach (var post in item.Posts)
{
<article class="archive-item">
<NavLink href="@("/post"+post.Url)">@post.Title</NavLink>
<span class="archive-item-date">@post.CreationTime</span>
</article>
}
}
}
else
{
<ErrorTip />
}
</div>
</div>
}
文章列表(标签)
Posts.Tag.razor
是根据标签查询文章列表,这个和分类查询文章列表实现方式一样,直接上代码。
@code {
/// <summary>
/// 标签名称参数
/// </summary>
[Parameter]
public string name { get; set; }
/// <summary>
/// 标签名称
/// </summary>
private string tagName;
/// <summary>
/// 文章列表数据
/// </summary>
private ServiceResult<IEnumerable<QueryPostDto>> posts;
/// <summary>
/// 初始化
/// </summary>
protected override async Task OnInitializedAsync()
{
// TODO:获取数据,可以在API中合并这两个请求。
var tag = await Http.GetFromJsonAsync<ServiceResult<string>>($"/blog/tag?name={name}");
posts = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryPostDto>>>($"/blog/posts/tag?name={name}");
if (tag.Success)
{
tagName = tag.Result;
}
}
}
@if (posts == null)
{
<Loading />
}
else
{
<div class="container">
<div class="post-wrap tags">
@if (tagName != null)
{
<h2 class="post-title">- Tag · @tagName -</h2>
}
</div>
<div class="post-wrap archive">
@if (posts.Success && posts.Result.Any())
{
@foreach (var item in posts.Result)
{
<h3>@item.Year</h3>
@foreach (var post in item.Posts)
{
<article class="archive-item">
<NavLink href="@("/post"+post.Url)">@post.Title</NavLink>
<span class="archive-item-date">@post.CreationTime</span>
</article>
}
}
}
else
{
<ErrorTip />
}
</div>
</div>
}
以上完成了以上几个页面的数据绑定,页面之间的跳转已经关联起来了,然后还剩下文章详情页,大家可以先自己动手完成它,今天就到这里,未完待续...
开源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)的更多相关文章
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
随机推荐
- 4.4 Go goto continue break
4.4 Go goto continue break Go语言的goto语句可以无条件的跳转到指定的代码行执行. goto语句一般与条件语句结合,实现条件转义,跳出循环体等. Go程序不推荐使用got ...
- Jquery获取select option动态添加自定义属性值失效
Jquery获取select option动态添加自定义属性值失效 2014/12/31 11:49:19 中国学网转载 编辑:李强 http://www.xue163.com/588880/3909 ...
- .Net基础之1——学前入门
1..Net平台 2.C#编程语言 3..Net都能做什么 Winform桌面应用程序.Internet应用程序——ASP.Net(京东.淘宝.携程网)(主推). WP8手机开发.Unity 3D游戏 ...
- 【HTTP】Web服务器和HTTP的协作&HTTP首部
用单台虚拟主机实现多个域名 Web服务器可以搭建多个独立域名的Web网站,也可以作为通信路径上的中转服务器提升效率. HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点,提供Web托管服务的 ...
- 【java】关键字volatile
volatile 1. 含义: volatile是JVM提供的轻量级的同步机制,具有三个特点:保证可见性.不保证原子性.禁止指令重排. 1.1 保证可见性 一个线程修改了共享变量并写回主内存,其他线程 ...
- spring cloud系列教程第六篇-Eureka集群版
spring cloud系列教程第六篇-Eureka集群版 本文主要内容: 本文来源:本文由凯哥Java(kaigejava)发布在博客园博客的.转载请注明 1:Eureka执行步骤理解 2:集群原理 ...
- 4.Linux的目录结构
Linux的目录结构 (1)"/"目录 Linux文件系统的入口,也是出于最高一级的目录 (2)"/bin" 基础系统所需要的那些命令位于此目录.也是最小系统所 ...
- [批处理教程之Shell]001.文本处理
在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器).它类似于DOS下的command和后来的cmd.exe.它接收用户命令,然后调用相应的应用程序. 同时 ...
- 最小生成树——Kruskal算法理解
背景:本文是在小甲鱼数据结构教学视频中的代码的基础上,添加详细注释而完成的.该段代码并不完整,仅摘录了核心算法部分,结合自己的思考,谈谈理解. Prim算法理解: 如图(摘录自小甲鱼教学视频中的图片) ...
- CTR学习笔记&代码实现6-深度ctr模型 后浪 xDeepFM/FiBiNET
xDeepFM用改良的DCN替代了DeepFM的FM部分来学习组合特征信息,而FiBiNET则是应用SENET加入了特征权重比NFM,AFM更进了一步.在看两个model前建议对DeepFM, Dee ...