series
- Develop blog projects based on ABP vNext and.NET Core – build projects using ABP CLI
- Develop blog projects based on ABP vNext and.NET Core – slim the project down and make it run
- Development blog project based on ABP vNext and.NET Core – Refinement and beautification, Swagger enter
- Develop blog project based on ABP vNext and.NET Core – data access and code priority
- Development blog project based on ABP vNext and.NET Core – add, delete, change and check custom warehouse
- Develop blog project based on ABP vNext and.NET Core – Uniform specification API, wrapper back model
- Develop blog projects based on ABP vNext and.NET Core – say Swagger, grouping, description, little green lock
- Develop blog projects based on ABP vNext and.NET Core – access GitHub and protect your API with JWT
- Develop blog project based on ABP vNext and.NET Core – exception handling and logging
- Develop blog projects based on ABP vNext and.NET Core – using Redis to cache data
- Develop blog project based on ABP vNext and.NET Core – integrate Hangfire for timed task processing
- Develop blog projects based on ABP vNext and.NET Core – Use AutoMapper to map objects
- Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (Part 1)
- Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (Part 2)
- Developing blog projects based on ABP vNext and.NET Core – Best Practices for Timed Tasks (PART 3)
- Blog Development project based on ABP vNext and.NET Core
- Abp vNext and.NET Core
- Blog Development project based on ABP vNext and.NET Core
- Blog Development project based on ABP vNext and.NET Core
- Blog Development project based on ABP vNext and.NET Core
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor – Part 2
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor – Part 6
- Abp vNext and.NET Core Development Blog Project – Blazor
- Abp vNext and.NET Core Development Blog Project – Blazor Series (8)
- Abp vNext and.NET Core Development Blog Project – Blazor Series (9)
- Abp vNext and.NET Core development blog project – Final release project
The last chapter completed all the functions of the background classification module, this chapter continues to add, delete, change and check the tag module and the friendship link module.
Label management
The implementation is the same as the previous classification management, add Tags. Razor component under the Admin folder, set route @page “/ Admin/Tags “.
The same thing needs to be placed under the AdminLayout component, adding a few parameters: Popover status bool Open, New or updated tag field string tagName ServiceResult
> Tags.
/// <summary>
///Hide Box by default
/// </summary>
private bool Open { get; set; } = false;
/// <summary>
///Add or update the label field value
/// </summary>
private string tagName, displayName;
/// <summary>
///Update the Id value of the label
/// </summary>
private int id;
/// <summary>
///The tag list data returned by the API
/// </summary>
private ServiceResult<IEnumerable<QueryTagForAdminDto>> tags;
Copy the code
//QueryTagForAdminDto.cs
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class QueryTagForAdminDto : QueryTagDto
{
/// <summary>
///A primary key
/// </summary>
public int Id { get; set; }}}Copy the code
Get the data in the initialization method OnInitializedAsync().
/// <summary>
///Initialize the
/// </summary>
/// <returns></returns>
protected override async Task OnInitializedAsync()
{
var token = await Common.GetStorageAsync("token");
Http.DefaultRequestHeaders.Add("Authorization".$"Bearer {token}");
tags = await FetchData();
}
/// <summary>
///To get the data
/// </summary>
/// <returns></returns>
private async Task<ServiceResult<IEnumerable<QueryTagForAdminDto>>> FetchData()
{
return await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryTagForAdminDto>>>("/blog/admin/tags");
}
Copy the code
Note that you need to set up the request header, grant access, and bind data on the page.
<AdminLayout>
@if (tags == null)
{
<Loading />
}
else
{
<div class="post-wrap tags">
<h2 class="post-title">- Tags -</h2>
@if (tags.Success && tags.Result.Any())
{
<div class="categories-card">
@foreach (var item in tags.Result)
{
<div class="card-item">
<div class="categories">
<NavLink title="ā delete" @onclick="@(async () => await DeleteAsync(item.Id))">ā</NavLink>
<NavLink title="š editor" @onclick="@(() => ShowBox(item))">š</NavLink>
<NavLink target="_blank" href="@ ($"/tag/ {item.DisplayName}")">
<h3>@item.TagName</h3>
<small>(@item.Count)</small>
</NavLink>
</div>
</div>
}
<div class="card-item">
<div class="categories">
<NavLink><h3 @onclick="@(() => ShowBox())">š~~~ Add labels ~~~š</h3></NavLink>
</div>
</div>
</div>
}
else
{
<ErrorTip />
}
</div>
<Box OnClickCallback="@SubmitAsync" Open="@Open">
<div class="box-item">
<b>DisplayName:</b><input type="text" @bind="@displayName" @bind:event="oninput" />
</div>
<div class="box-item">
<b>TagName:</b><input type="text" @bind="@tagName" @bind:event="oninput" />
</div>
</Box>
}
</AdminLayout>
Copy the code
Tags displays
The
component binds two parameters of the label, whether to open the Opne parameter and confirm the button callback event method SubmitAsync().
Delete tag method DeleteAsync(…) As follows:
// Popup confirmation
bool confirmed = await Common.InvokeAsync<bool> ("confirm"."\nš„š¢ Really want to kill this damn tag š¢š„");
if (confirmed)
{
var response = await Http.DeleteAsync($"/blog/tag? id={id}");
var result = await response.Content.ReadFromJsonAsync<ServiceResult>();
if (result.Success)
{
tags = awaitFetchData(); }}Copy the code
Confirm the deletion again before deleting the data to avoid accidental damage.
Popover method ShowBox(…) As follows:
/// <summary>
///Show box, bind field
/// </summary>
/// <param name="dto"></param>
private void ShowBox(QueryTagForAdminDto dto = null)
{
Open = true;
id = 0;
/ / new
if (dto == null)
{
displayName = null;
tagName = null;
}
else / / update{ id = dto.Id; displayName = dto.DisplayName; tagName = dto.TagName; }}Copy the code
Finally, confirm the button’s callback event method SubmitAsync() in the popover as follows:
/// <summary>
///Confirm button click event
/// </summary>
/// <returns></returns>
private async Task SubmitAsync()
{
var input = new EditTagInput()
{
DisplayName = displayName.Trim(),
TagName = tagName.Trim()
};
if (string.IsNullOrEmpty(input.DisplayName) || string.IsNullOrEmpty(input.TagName))
{
return;
}
var responseMessage = new HttpResponseMessage();
if (id > 0)
responseMessage = await Http.PutAsJsonAsync($"/blog/tag? id={id}", input);
else
responseMessage = await Http.PostAsJsonAsync("/blog/tag", input);
var result = await responseMessage.Content.ReadFromJsonAsync<ServiceResult>();
if (result.Success)
{
tags = await FetchData();
Open = false; }}Copy the code
The input parameter EditTagInput.
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class EditTagInput : TagDto{}}Copy the code
The final execution of adding or updating data is carried out in the click event, assigning the value of the variable to EditTagInput, judging whether to add or update according to the ID, reloading the data after success, and closing the popover.
Label management page code is as follows:
Click to see the code
@page "/admin/categories"
<AdminLayout>
@if (categories == null)
{
<Loading />
}
else
{
<div class="post-wrap categories">
<h2 class="post-title">- Categories -</h2> @if (categories.Success && categories.Result.Any())
{
<div class="categories-card">
@foreach (var item in categories.Result)
{
<div class="card-item">
<div class="categories">
<NavLink title="ā delete" @onclick="@(async () => await DeleteAsync(item.Id))"> ā < / NavLink > < NavLink title ="š editor" @onclick="@(() => ShowBox(item))"> š < / NavLink > < NavLink target ="_blank" href="@ ($"/category/{item.DisplayName}")">
<h3>@item.CategoryName</h3>
<small>(@item.Count)</small>
</NavLink>
</div>
</div>
}
<div class="card-item">
<div class="categories">
<NavLink><h3 @onclick="@(() => ShowBox())"New classification > š ~ ~ ~ ~ ~ ~ š < / h3 > < / NavLink > < / div > < / div > < / div >}else
{
<ErrorTip />
}
</div>
<Box OnClickCallback="@SubmitAsync" Open="@Open">
<div class="box-item">< b>DisplayName: </b><input type="text" @bind="@displayName" @bind:event="oninput" />
</div>
<div class="box-item">< b>CategoryName: </b><input type="text" @bind="@categoryName" @bind:event="oninput" />
</div>
</Box>
}
</AdminLayout>
@code {
/// <summary>
///Hide Box by default
/// </summary>
private bool Open { get; set; } = false;
/// <summary>
///New or updated category field value
/// </summary>
private string categoryName, displayName;
/// <summary>
///Update the Id value of a category
/// </summary>
private int id;
/// <summary>
///The category list data returned by the API
/// </summary>
private ServiceResult<IEnumerable<QueryCategoryForAdminDto>> categories;
/// <summary>
///Initialize the
/// </summary>
/// <returns></returns>
protected override async Task OnInitializedAsync()
{
var token = await Common.GetStorageAsync("token");
Http.DefaultRequestHeaders.Add("Authorization".$"Bearer {token}");
categories = await FetchData();
}
/// <summary>
///To get the data
/// </summary>
/// <returns></returns>
private async Task<ServiceResult<IEnumerable<QueryCategoryForAdminDto>>> FetchData()
{
return await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryCategoryForAdminDto>>>("/blog/admin/categories");
}
/// <summary>
///Delete the classification
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private async Task DeleteAsync(int id)
{
Open = false;
// Popup confirmation
bool confirmed = await Common.InvokeAsync<bool> ("confirm"."\nš„š¢ Really want to kill this damn classification š¢š„");
if (confirmed)
{
var response = await Http.DeleteAsync($"/blog/category? id={id}");
var result = await response.Content.ReadFromJsonAsync<ServiceResult>();
if (result.Success)
{
categories = awaitFetchData(); }}}/// <summary>
///Show box, bind field
/// </summary>
/// <param name="dto"></param>
private void ShowBox(QueryCategoryForAdminDto dto = null)
{
Open = true;
id = 0;
/ / new
if (dto == null)
{
displayName = null;
categoryName = null;
}
else / / update{ id = dto.Id; displayName = dto.DisplayName; categoryName = dto.CategoryName; }}/// <summary>
///Confirm button click event
/// </summary>
/// <returns></returns>
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);
else
responseMessage = await Http.PostAsJsonAsync("/blog/category", input);
var result = await responseMessage.Content.ReadFromJsonAsync<ServiceResult>();
if (result.Success)
{
categories = await FetchData();
Open = false; }}}Copy the code
Friends of chain management
The implementation is the same, this is not to say, directly on the code.
First add the receive parameter returned by the API and the input parameter of the new edit.
//QueryFriendLinkForAdminDto.cs
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class QueryFriendLinkForAdminDto : FriendLinkDto
{
/// <summary>
///A primary key
/// </summary>
public int Id { get; set; }}}//EditFriendLinkInput.cs
namespace Meowv.Blog.BlazorApp.Response.Blog
{
public class EditFriendLinkInput : FriendLinkDto{}}Copy the code
@page "/admin/friendlinks"
<AdminLayout>
@if (friendlinks == null)
{
<Loading />
}
else
{
<div class="post-wrap categories">
<h2 class="post-title">- FriendLinks -</h2> @if (friendlinks.Success && friendlinks.Result.Any())
{
<div class="categories-card">
@foreach (var item in friendlinks.Result)
{
<div class="card-item">
<div class="categories">
<NavLink title="ā delete" @onclick="@(async () => await DeleteAsync(item.Id))"> ā < / NavLink > < NavLink title ="š editor" @onclick="@(() => ShowBox(item))"> š < / NavLink > < NavLink target ="_blank" href="@item.LinkUrl">
<h3>@item.Title</h3>
</NavLink>
</div>
</div>
}
<div class="card-item">
<div class="categories">
<NavLink><h3 @onclick="@(() => ShowBox())"> š chain of new friends ~ ~ ~ ~ ~ ~ š < / h3 > < / NavLink > < / div > < / div > < / div >}else
{
<ErrorTip />
}
</div>
<Box OnClickCallback="@SubmitAsync" Open="@Open">
<div class="box-item">< b>Title: </b><input type="text" @bind="@title" @bind:event="oninput" />
</div>
<div class="box-item"LinkUrl: </b><input type="text" @bind="@linkUrl" @bind:event="oninput" />
</div>
</Box>
}
</AdminLayout>
@code {
/// <summary>
///Hide Box by default
/// </summary>
private bool Open { get; set; } = false;
/// <summary>
///Add or update the value of the friend chain field
/// </summary>
private string title, linkUrl;
/// <summary>
///Update the Id value of the friend chain
/// </summary>
private int id;
/// <summary>
///The list of friends returned by the API
/// </summary>
private ServiceResult<IEnumerable<QueryFriendLinkForAdminDto>> friendlinks;
/// <summary>
///Initialize the
/// </summary>
/// <returns></returns>
protected override async Task OnInitializedAsync()
{
var token = await Common.GetStorageAsync("token");
Http.DefaultRequestHeaders.Add("Authorization".$"Bearer {token}");
friendlinks = await FetchData();
}
/// <summary>
///To get the data
/// </summary>
/// <returns></returns>
private async Task<ServiceResult<IEnumerable<QueryFriendLinkForAdminDto>>> FetchData()
{
return await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryFriendLinkForAdminDto>>>("/blog/admin/friendlinks");
}
/// <summary>
///Delete the classification
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private async Task DeleteAsync(int id)
{
Open = false;
// Popup confirmation
bool confirmed = await Common.InvokeAsync<bool> ("confirm"."\nš„š¢ Really want to kill this damn classification š¢š„");
if (confirmed)
{
var response = await Http.DeleteAsync($"/blog/friendlink? id={id}");
var result = await response.Content.ReadFromJsonAsync<ServiceResult>();
if (result.Success)
{
friendlinks = awaitFetchData(); }}}/// <summary>
///Show box, bind field
/// </summary>
/// <param name="dto"></param>
private void ShowBox(QueryFriendLinkForAdminDto dto = null)
{
Open = true;
id = 0;
/ / new
if (dto == null)
{
title = null;
linkUrl = null;
}
else / / update{ id = dto.Id; title = dto.Title; linkUrl = dto.LinkUrl; }}/// <summary>
///Confirm button click event
/// </summary>
/// <returns></returns>
private async Task SubmitAsync()
{
var input = new EditFriendLinkInput()
{
Title = title.Trim(),
LinkUrl = linkUrl.Trim()
};
if (string.IsNullOrEmpty(input.Title) || string.IsNullOrEmpty(input.LinkUrl))
{
return;
}
var responseMessage = new HttpResponseMessage();
if (id > 0)
responseMessage = await Http.PutAsJsonAsync($"/blog/friendlink? id={id}", input);
else
responseMessage = await Http.PostAsJsonAsync("/blog/friendlink", input);
var result = await responseMessage.Content.ReadFromJsonAsync<ServiceResult>();
if (result.Success)
{
friendlinks = await FetchData();
Open = false; }}}Copy the code
So far, the function of the remaining article module has not been done, today I will stop here, tomorrow will continue, to be continued…
Open source: github.com/Meowv/Blog/…