系列文章

  1. 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目
  2. 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来
  3. 基于 abp vNext 和 .NET Core 开发博客项目 - 完善与美化,Swagger登场
  4. 基于 abp vNext 和 .NET Core 开发博客项目 - 数据访问和代码优先
  5. 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查
  6. 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
  7. 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
  8. 基于 abp vNext 和 .NET Core 开发博客项目 - 接入GitHub,用JWT保护你的API
  9. 基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
  10. 基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据
  11. 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
  12. 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
  13. 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(一)
  14. 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)
  15. 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(三)
  16. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)
  17. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
  18. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
  19. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(四)
  20. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
  21. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
  22. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
  23. 基于 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">-&nbsp;Categories&nbsp;-</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">-&nbsp;Tags&nbsp;-</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">-&nbsp;FriendLinks&nbsp;-</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">-&nbsp;Category&nbsp;·&nbsp;@categoryName&nbsp;-</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">-&nbsp;Tag&nbsp;·&nbsp;@tagName&nbsp;-</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 实战系列(四)的更多相关文章

  1. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  2. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  3. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  4. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  5. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  6. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  7. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  8. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  9. 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

随机推荐

  1. 5.1 Go函数定义

    1 Go函数定义 Go函数是指:一段具有独立功能的代码,然后可以在程序中其他地方多次调用. Go分为自定义函数,系统函数. 函数可以将一个大的工作拆解成小的任务. 函数对用户隐藏了细节. Golang ...

  2. Django之templates模板

    模板渲染: 官方文档:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-for 模板渲染两种 ...

  3. zz 关于插入意向间隔锁( insert intention gap lock)产生的死锁问题

    出处: http://www.cnblogs.com/sunss/p/3166550.html 昨天看到一个很有意思的死锁,拿来记录下: 环境:deadlock on 事务隔离级别: read com ...

  4. Hbase javaAPI报错:Callexception,tries=10,retries=35,started=38465msago

    [client.RpcRetryingCaller(142)]Callexception,tries=10,retries=35,started=38465msago,cancelled=false, ...

  5. jquery 滚轴滚动 导航定位和锚点定位

    自己写的,只测试了ie9+, firefox,chrome 以下js更好 var fixbar={ init:function(){ "use strict"; // 滚轴 导航位 ...

  6. 【python爬虫】scrapy入门2--自定义item

    items.py class LianhezaobaospyderItem(scrapy.Item): # define the fields for your item here like: # n ...

  7. 数据库-第八章 数据库编程-8.4 ODBC编程

    ODBC编程 一.ODBC概述 二.ODBC工作原理概述 1.用户应用程序 2.ODBC驱动程序管理器 3.数据库驱动程序 4.数据源管理 5.小结 三.ODBC API基础 1.函数概述 2.句柄及 ...

  8. Flask SSTI | Python3 学习记录

    Flask SSTI | Python3 引言 昨天原本是打算继续python的每日一练的,这次按日程一样是要练习用一个web框架写一个留言板的,于是打算用flask搞一下,但是正打算写的时候,突然想 ...

  9. Spring_AOP_AspectJ支持的通知注解

    1.AOP前奏: 使用动态代理解决日志需求 ArithmeticCalculator.java package com.aff.spring.aop.helloworld; public interf ...

  10. Beta冲刺 —— 5.29

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.展示了每个人当天的成果. ...