欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 编程语言 > >内容正文

asp.net

基于 abp vnext 和 .net core 开发博客项目 -凯发k8官方网

发布时间:2025/1/21 15 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

基于 abp vnext 和 .net core 开发博客项目 - blazor 实战系列(六)

转载于:https://github.com/meowv/blog

上一篇完成了博客文章详情页面的数据展示和基于jwt方式的简单身份验证,本篇继续推进,完成后台分类管理的所有增删改查等功能。

分类管理

图片

在 admin 文件夹下新建razor组件,categories.razor,设置路由,@page “/admin/categories”。将具体的展示内容放在组件adminlayout中。

@page “/admin/categories”

在这里我会将所有分类展示出来,新增、更新、删除都会放在一个页面上去完成。

先将列表查出来,添加api的返回参数,private serviceresult categories;,然后再初始化中去获取数据。

//querycategoryforadmindto.cs
namespace meowv.blog.blazorapp.response.blog
{
public class querycategoryforadmindto : querycategorydto
{
///
/// 主键
///
public int id { get; set; }
}
}
///
/// api返回的分类列表数据
///
private serviceresult categories;

///
/// 初始化
///
///
protected override async task oninitializedasync()
{
var token = await common.getstorageasync(“token”);
http.defaultrequestheaders.add(“authorization”, $“bearer {token}”);

categories = await fetchdata();

}

///
/// 获取数据
///
///
private async task> fetchdata()
{
return await http.getfromjsonasync>("/blog/admin/categories");
}
初始化的时候,需要将我们存在localstorage中的token读取出来,因为我们后台的api都需要添加 authorization header 请求头才能成功返回数据。

在blazor添加请求头也是比较方便的,直接http.defaultrequestheaders.add(…)即可,要注意的是 token值前面需要加 bearer,跟了一个空格不可以省略。

获取数据单独提成了一个方法fetchdata(),因为会频繁用到,现在在页面上将数据绑定进行展示。

@if (categories == null)
{

}
else
{


- categories -


@if (categories.success && categories.result.any())
{

@foreach (var item in categories.result)
{



📝

@item.categoryname


(@item.count)



}


📕~~~ 新增分类 ~~~📕



}
else
{

}

}
同样的当categories还没成功获取到数据的时候,我们直接在展示 组件。然后就是循环列表数据在foreach中进行绑定数据。

在每条数据最前面,加了删除和编辑两个按钮,删除的时候调用deleteasync方法,将当前分类的id传给他即可。新增和编辑的时候调用showbox方法,他接受一个参数,当前循环到的分类对象item,即querycategoryforadmindto。

同时这里考虑到复用性,我写了一个弹窗组件,box.razor,放在shared文件夹下面,可以先看一下标题为弹窗组件的内容再回来继续往下看。

删除分类

接下来看看删除方法。

///
/// 删除分类
///
///
///
private async task deleteasync(int id)
{
// 弹窗确认
bool confirmed = await common.invokeasync(“confirm”, “\n💥💢真的要干掉这个该死的分类吗💢💥”);

if (confirmed) {var response = await http.deleteasync($"/blog/category?id={id}");var result = await response.content.readfromjsonasync();if (result.success){categories = await fetchdata();} }

}
删除之前搞个原生的confirm进行提示,避免手残误删。因为api那边使用的是httpdelete,所有我们调用api时候要用http.deleteasync,返回的是httpresponsemessage对象,需要我们手动处理接收返回数据,将其转换为serviceresult对象,如果判断删除成功后重新调用fetchdata()刷新分类数据。

图片

新增/更新分类

新增和更新数据选择使用弹窗的方式来进行(弹窗组件在下方),首先是需要一个参数判断弹窗是否打开,因为是将新增和更新放在一起,所以如何判断是新增还是更新呢?这里使用id来进行判断,当编辑的时候肯定会有id参数。新增的时候是没有参数传递的。

当我们打开弹窗后里面需要展示两个input框,用来供输入要保存的数据,同样是添加两个变量。

添加所需的这几个参数。

///
/// 默认隐藏box
///
private bool open { get; set; } = false;

///
/// 新增或者更新时候的分类字段值
///
private string categoryname, displayname;

///
/// 更新分类的id值
///
private int id;
现在可以将box组件添加到页面上。

... displayname:

添加了两个input,将两个分类字段分别绑定上去,使用@bind和@bind:event。前者等价于设置其value值,后者等价于一个change事件当值改变后会重新赋给绑定的字段参数。

现在可以来看看点击了新增或者编辑按钮的方法showbox(…),接收一个参数querycategoryforadmindto让其默认值为null。

///
/// 显示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; }

}
执行showbox()方法,将弹窗打开,设置open = true;和初始化id的值id = 0;。

通过参数是否null进行判断是新增还是更新,这样打开弹窗就搞定了,剩下的就交给弹窗来处理了。

因为新增和更新api需要还对应的输入参数editcategoryinput,去添加它不要忘了。

那么现在就只差按钮回调事件submitasync()了,主要是给输入参数进行赋值调用api,执行新增或者更新即可。

///
/// 确认按钮点击事件
///
///
private async task submitasync()
{
var input = new editcategoryinput()
{
displayname = displayname.trim(),
categoryname = categoryname.trim()
};

if (string.isnullorempty(input.displayname) || string.isnullorempty(input.categoryname)) {return; }var responsemessage = new httpresponsemessage();if (id > 0)responsemessage = await http.putasjsonasync($"/blog/category?id={id}", input); elseresponsemessage = await http.postasjsonasync("/blog/category", input);var result = await responsemessage.content.readfromjsonasync(); if (result.success) {categories = await fetchdata();open = false; }

}
当参数为空时,直接return什么都不执行。通过当前id判断是新增还是更新操作,调用不同的方法putasjsonasync和postasjsonasync去请求api,同样返回到是httpresponsemessage对象,最后如果操作成功,重新请求一个数据,刷新分类列表,将弹窗关闭掉。

分类管理页面的全部代码如下:

@page “/admin/categories”

@if (categories == null) { } else {

- categories -

@if (categories.success && categories.result.any()) { @foreach (var item in categories.result) {

@code {
///
/// 默认隐藏box
///
private bool open { get; set; } = false;

/// /// 新增或者更新时候的分类字段值 /// private string categoryname, displayname;/// /// 更新分类的id值 /// private int id;/// /// api返回的分类列表数据 /// private serviceresult> categories;/// /// 初始化 /// /// protected override async task oninitializedasync() {var token = await common.getstorageasync("token");http.defaultrequestheaders.add("authorization", $"bearer {token}");categories = await fetchdata(); }/// /// 获取数据 /// /// private async task>> fetchdata() {return await http.getfromjsonasync>>("/blog/admin/categories"); }/// /// 删除分类 /// /// /// private async task deleteasync(int id) {open = false;// 弹窗确认bool confirmed = await common.invokeasync("confirm", "\n💥💢真的要干掉这个该死的分类吗💢💥");if (confirmed){var response = await http.deleteasync($"/blog/category?id={id}");var result = await response.content.readfromjsonasync();if (result.success){categories = await fetchdata();}} }/// /// 显示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;} }/// /// 确认按钮点击事件 /// /// private async task submitasync() {var input = new editcategoryinput(){displayname = displayname.trim(),categoryname = categoryname.trim()};if (string.isnullorempty(input.displayname) || string.isnullorempty(input.categoryname)){return;}var responsemessage = new httpresponsemessage();if (id > 0)responsemessage = await http.putasjsonasync($"/blog/category?id={id}", input);elseresponsemessage = await http.postasjsonasync("/blog/category", input);var result = await responsemessage.content.readfromjsonasync();if (result.success){categories = await fetchdata();open = false;} }

}
图片

弹窗组件

考虑到新增和更新数据的时候需要弹窗,这里就简单演示一下写一个小组件。

在 shared 文件夹下新建一个box.razor。

在开始之前分析一下弹窗组件所需的元素,弹窗肯定有一个确认和取消按钮,右上角需要有一个关闭按钮,关闭按钮和取消按钮一个意思。他还需要一个打开或者关闭的状态,判断是否打开弹窗,还有就是弹窗内需要自定义展示内容。

确定按钮的文字可以自定义,所以差不多就需要3个参数,组件内容renderfragment childcontent,是否打开弹窗bool open默认隐藏,按钮文字string buttontext默认值给"确定"。然后最重要的是确定按钮需要一个回调事件,eventcallback onclickcallback 用于执行不同的事件。

///
/// 组件内容
///
[parameter]
public renderfragment childcontent { get; set; }

///
/// 是否隐藏
///
[parameter]
public bool open { get; set; } = true;

///
/// 按钮文字
///
[parameter]
public string buttontext { get; set; } = “确定”;

///
/// 确认按钮点击事件回调
///
[parameter]
public eventcallback onclickcallback { get; set; }

///
/// 关闭box
///
private void close() => open = false;
右上角关闭和取消按钮直接在内部进行处理,执行close()方法,将参数open值设置为false即可。

对应的html如下。

@if (open)
{





@childcontent

网站地图