基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
2021-02-05 10:16
标签:内容 方法 有一个 lang arp parameter void 类对象 存在 上一篇完成了博客文章详情页面的数据展示和基于JWT方式的简单身份验证,本篇继续推进,完成后台分类管理的所有增删改查等功能。 在 Admin 文件夹下新建Razor组件, 在这里我会将所有分类展示出来,新增、更新、删除都会放在一个页面上去完成。 先将列表查出来,添加API的返回参数, 初始化的时候,需要将我们存在 在Blazor添加请求头也是比较方便的,直接 获取数据单独提成了一个方法 同样的当categories还没成功获取到数据的时候,我们直接在展示 在每条数据最前面,加了删除和编辑两个按钮,删除的时候调用 同时这里考虑到复用性,我写了一个弹窗组件, 接下来看看删除方法。 删除之前搞个原生的 新增和更新数据选择使用弹窗的方式来进行(弹窗组件在下方),首先是需要一个参数判断弹窗是否打开,因为是将新增和更新放在一起,所以如何判断是新增还是更新呢?这里使用Id来进行判断,当编辑的时候肯定会有Id参数。新增的时候是没有参数传递的。 当我们打开弹窗后里面需要展示两个input框,用来供输入要保存的数据,同样是添加两个变量。 添加所需的这几个参数。 现在可以将Box组件添加到页面上。 确定按钮回调事件执行 添加了两个input,将两个分类字段分别绑定上去,使用 现在可以来看看点击了新增或者编辑按钮的方法 执行 通过参数是否null进行判断是新增还是更新,这样打开弹窗就搞定了,剩下的就交给弹窗来处理了。 因为新增和更新API需要还对应的输入参数 那么现在就只差按钮回调事件 当参数为空时,直接 分类管理页面的全部代码如下: 考虑到新增和更新数据的时候需要弹窗,这里就简单演示一下写一个小组件。 在 Shared 文件夹下新建一个 在开始之前分析一下弹窗组件所需的元素,弹窗肯定有一个确认和取消按钮,右上角需要有一个关闭按钮,关闭按钮和取消按钮一个意思。他还需要一个打开或者关闭的状态,判断是否打开弹窗,还有就是弹窗内需要自定义展示内容。 确定按钮的文字可以自定义,所以差不多就需要3个参数,组件内容 右上角关闭和取消按钮直接在内部进行处理,执行 对应的html如下。 下面是弹窗组件所需的样式代码,大家需要的自取,也可以直接去GitHub实时获取最新的样式文件。 好了,分类模块的功能都完成了,标签和友情链接的管理界面还会远吗?这两个模块的做法和分类是一样的,有兴趣的可以自己动手完成,今天到这吧,未完待续... 开源地址:https://github.com/Meowv/Blog/tree/blog_tutorial 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六) 标签:内容 方法 有一个 lang arp parameter void 类对象 存在 原文地址:https://www.cnblogs.com/meowv/p/13124303.html系列文章
分类管理
Categories.razor
,设置路由,@page "/admin/categories"
。将具体的展示内容放在组件AdminLayout
中。@page "/admin/categories"
private ServiceResult
,然后再初始化中去获取数据。//QueryCategoryForAdminDto.cs
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class QueryCategoryForAdminDto : QueryCategoryDto
{
///
///
localStorage
中的token读取出来,因为我们后台的API都需要添加 Authorization
Header 请求头才能成功返回数据。Http.DefaultRequestHeaders.Add(...)
即可,要注意的是 token值前面需要加 Bearer
,跟了一个空格不可以省略。FetchData()
,因为会频繁用到,现在在页面上将数据绑定进行展示。@if (categories == null)
{
- Categories -
@if (categories.Success && categories.Result.Any())
{
@item.CategoryName
(@item.Count)
ShowBox())">??~~~ 新增分类 ~~~??
组件。然后就是循环列表数据在foreach
中进行绑定数据。DeleteAsync
方法,将当前分类的Id传给他即可。新增和编辑的时候调用ShowBox
方法,他接受一个参数,当前循环到的分类对象item,即QueryCategoryForAdminDto
。Box.Razor
,放在Shared文件夹下面,可以先看一下标题为弹窗组件的内容再回来继续往下看。删除分类
///
confirm
进行提示,避免手残误删。因为API那边使用的是HttpDelete
,所有我们调用API时候要用Http.DeleteAsync
,返回的是HttpResponseMessage
对象,需要我们手动处理接收返回数据,将其转换为ServiceResult
对象,如果判断删除成功后重新调用FetchData()
刷新分类数据。新增/更新分类
///
SubmitAsync()
方法,打开状态参数为上面添加的Open
,按钮文字ButtonText
为默认值不填。@bind
和@bind:event
。前者等价于设置其value值,后者等价于一个change事件当值改变后会重新赋给绑定的字段参数。ShowBox(...)
,接收一个参数QueryCategoryForAdminDto
让其默认值为null。///
ShowBox()
方法,将弹窗打开,设置Open = true;
和初始化id的值id = 0;
。EditCategoryInput
,去添加它不要忘了。SubmitAsync()
了,主要是给输入参数进行赋值调用API,执行新增或者更新即可。///
return
什么都不执行。通过当前Id判断是新增还是更新操作,调用不同的方法PutAsJsonAsync
和PostAsJsonAsync
去请求API,同样返回到是HttpResponseMessage
对象,最后如果操作成功,重新请求一个数据,刷新分类列表,将弹窗关闭掉。点击查看代码
@page "/admin/categories"
@if (categories == null)
{
- Categories -
@if (categories.Success && categories.Result.Any())
{
@item.CategoryName
(@item.Count)
ShowBox())">??~~~ 新增分类 ~~~??
/// 默认隐藏Box
///
private bool Open { get; set; } = false;
///
/// 新增或者更新时候的分类字段值
///
private string categoryName, displayName;
///
/// 更新分类的Id值
///
private int id;
///
/// API返回的分类列表数据
///
private ServiceResult
/// 初始化
///
///
/// 获取数据
///
///
/// 删除分类
///
///
///
/// 显示box,绑定字段
///
///
private void ShowBox(QueryCategoryForAdminDto dto = null)
{
Open = true;
id = 0;
// 新增
if (dto == null)
{
displayName = null;
categoryName = null;
}
else // 更新
{
id = dto.Id;
displayName = dto.DisplayName;
categoryName = dto.CategoryName;
}
}
///
/// 确认按钮点击事件
///
/// 弹窗组件
Box.razor
。RenderFragment ChildContent
,是否打开弹窗bool Open
默认隐藏,按钮文字string ButtonText
默认值给"确定"。然后最重要的是确定按钮需要一个回调事件,EventCallback
用于执行不同的事件。///
Close()
方法,将参数Open
值设置为false即可。@if (Open)
{
关于样式
.box {
width: 600px;
height: 300px;
border-radius: 5px;
background-color: #fff;
position: fixed;
top: 50%;
left: 50%;
margin-top: -150px;
margin-left: -300px;
z-index: 997;
}
.close {
position: absolute;
right: 3px;
top: 2px;
cursor: pointer;
}
.shadow {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
z-index: 996;
background-color: #000;
opacity: 0.3;
}
.box-content {
width: 90%;
margin: 20px auto;
}
.box-item {
margin-top: 10px;
height: 30px;
}
.box-item b {
width: 130px;
display: inline-block;
}
.box-item input[type=text] {
padding-left: 5px;
width: 300px;
height: 30px;
}
.box-item label {
width: 100px;
white-space: nowrap;
}
.box-item input[type=radio] {
width: auto;
height: auto;
visibility: initial;
display: initial;
margin-right: 2px;
}
.box-item button {
height: 30px;
width: 100px;
}
.box-item-btn {
position: absolute;
right: 20px;
bottom: 20px;
}
.box-btn {
display: inline-block;
height: 30px;
line-height: 30px;
padding: 0 18px;
background-color: #5A9600;
color: #fff;
white-space: nowrap;
text-align: center;
font-size: 14px;
border: none;
border-radius: 2px;
cursor: pointer;
}
button:focus {
outline: 0;
}
.box-btn:hover {
opacity: .8;
filter: alpha(opacity=80);
color: #fff;
}
.btn-primary {
border: 1px solid #C9C9C9;
background-color: #fff;
color: #555;
}
.btn-primary:hover {
border-color: #5A9600;
color: #333;
}
.post-box {
width: 98%;
margin: 27px auto 0;
}
.post-box-item {
width: 100%;
height: 30px;
margin-bottom: 5px;
}
.post-box-item input {
width: 49.5%;
height: 30px;
padding-left: 5px;
border: 1px solid #ddd;
}
.post-box-item input:nth-child(1) {
float: left;
margin-right: 1px;
}
.post-box-item input:nth-child(2) {
float: right;
margin-left: 1px;
}
.post-box .box-item b {
width: auto;
}
.post-box .box-item input[type=text] {
width: 90%;
}
上一篇:【JS】07 JS对象
文章标题:基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
文章链接:http://soscw.com/essay/51290.html