在本节中,您将学习如何创建新的模式对话框形式来创建新书。模态对话框如下图所示:
在ABPBookStore.Web项目的
Pages/Books文件夹下,创建一个
razor页面命名为CreateModal.cshtml,
打开CreateModal.cshtml.cs
文件(CreateModalModel
类)并替换为以下代码:
namespace ABPBookStore.Web.Pages.Books
{
public class CreateModalModel : ABPBookStorePageModel
{
[BindProperty]
public CreateUpdateBookDto Book { get; set; }
private readonly IBookAppService _bookAppService;
public CreateModalModel(IBookAppService bookAppService)
{
_bookAppService = bookAppService;
}
public async Task
{
await _bookAppService.CreateAsync(Book);
return NoContent();
}
}
}
BookStorePageModel而
不是standard 派生PageModel
。BookStorePageModel
继承PageModel
并添加一些可以在页面模型类中使用的常见属性和方法。[BindProperty]
属性上的Book
属性将发布请求数据绑定到该属性。IBookAppService
构造函数中,并CreateAsync
在OnPostAsync
处理程序中调用方法。CreateModal.cshtml
打开CreateModal.cshtml
文件并粘贴以下代码:
@page
@inherits ABPBookStore.Web.Pages.ABPBookStorePage
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model ABPBookStore.Web.Pages.Books.CreateModalModel
@{
Layout = null;
}
此模态使用abp-dynamic-form
标签帮助程序从模型自动创建表单 CreateBookViewModel
。
abp-model
Book
在这种情况下,attribute指示模型对象所在的属性。data-ajaxForm
属性将表单设置为通过AJAX提交,而不是经典的页面post。abp-form-content
标记帮助器是呈现表单控件的占位符(仅当您在abp-dynamic-form
标记中添加了其他内容(如此页面一样)时才是可选的,并且是必需的)。打开Pages/Books/Index.cshtml
并设置abp-card-header
标签内容,如下所示:
@L["Books"]
icon="plus"
button-type="Primary" />
这增加了一个新按钮NewBook在右上角:
接下来打开pages/books/index.js
并在Datatable
配置之后添加以下代码:
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
createModal.onResult(function () {
dataTable.ajax.reload();
});
$('#NewBookButton').click(function (e) {
e.preventDefault();
createModal.open();
});
abp.ModalManager
是在客户端管理模式的助手类。它在内部使用Twitter Bootstrap的标准模式,但是通过提供一个简单的API来抽象许多细节。现在,您可以运行该应用程序并使用新的模式形式添加新书。
在 ABPBookStore.Web项目的Pages/Books文件夹下创建一个Razor页面命名为EditModal.cshtml
EditModal.cshtml.cs
打开EditModal.cshtml.cs
文件(EditModalModel
类)并替换为以下代码:
namespace ABPBookStore.Web.Pages.Books
{
public class EditModalModel : ABPBookStorePageModel
{
[HiddenInput]
[BindProperty(SupportsGet = true)]
public Guid Id { get; set; }
[BindProperty]
public CreateUpdateBookDto Book { get; set; }
private readonly IBookAppService _bookAppService;
public EditModalModel(IBookAppService bookAppService)
{
_bookAppService = bookAppService;
}
public async Task OnGetAsync()
{
var bookDto = await _bookAppService.GetAsync(Id);
Book = ObjectMapper.Map
}
public async Task
{
await _bookAppService.UpdateAsync(Id, Book);
return NoContent();
}
}
}
[HiddenInput]
和[BindProperty]
是标准的ASP.NET MVC的核心属性。SupportsGet
用于能够从请求的查询字符串参数获取Id
值。GetAsync
方法中,我们得到来自BookAppService的BookDto,
这个被映射到DTO对象CreateUpdateBookDto
。OnPostAsync
用BookAppService.UpdateAsync()方法
更新实体。为了能够将映射BookDto
到CreateUpdateBookDto
,请配置新的映射。在ABPBookStore.Web
项目中打开ABPBookStoreWebAutoMapperProfile.cs
并按如下所示进行更改:
public ABPBookStoreWebAutoMapperProfile()
{
//Define your AutoMapper configuration here for the Web project.
CreateMap
}
添加了CreateMap
定义此映射的功能。
用以下内容替换EditModal.cshtml
内容
@page
@inherits ABPBookStore.Web.Pages.ABPBookStorePage
@using ABPBookStore.Web.Pages.Books
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@model EditModalModel
@{
Layout = null;
}
该页面与CreateModal.cshtml
十分相似,除了:
abp-input
用于Id
存储Id
编辑书的属性(这是一个隐藏的输入)。Books/EditModal
用作发布URL,而“ Update”文本用作模式标题。我们将在表中添加一个名为Actions的下拉按钮。
打开Pages/Books/Index.cshtml
页面并更改
部分,如下所示:
@L["Actions"]
@L["Name"]
@L["Type"]
@L["PublishDate"]
@L["Price"]
@L["CreationTime"]
打开pages/books/index.js
并替换以下内容:
$(function () {
var l = abp.localization.getResource('ABPBookStore');
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
var editModal = new abp.ModalManager(abp.appPath + 'Books/EditModal');
var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
autoWidth: false,
scrollCollapse: true,
order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(aBPBookStore.book.getList),
columnDefs: [
{
rowAction: {
items:
[
{
text: l('Edit'),
action: function (data) {
editModal.open({ id: data.record.id });
}
}
]
}
},
{ data: "name" },
{ data: "type" },
{ data: "publishDate" },
{ data: "price" },
{ data: "creationTime" }
]
}));
createModal.onResult(function () {
dataTable.ajax.reload();
});
editModal.onResult(function () {
dataTable.ajax.reload();
});
$('#NewBookButton').click(function (e) {
e.preventDefault();
createModal.open();
});
});
abp.localization.getResource('ABPBookStore')
能够使用服务器端上定义的相同本地化文本。createModal的ModalManager
以打开“创建模式”对话框。editModal的
ModalManager
以打开编辑模式对话框。columnDefs
节的开头添加了新列。此列用于“ Actions ”下拉按钮。createModal.open()
即可打开创建对话框。editModal.open()
即可打开编辑对话框。您可以通过选择编辑操作来运行该应用程序并编辑任何书籍。最终的UI如下所示:
打开,pages/books/index.js
然后将新项添加到rowAction
items
:
{
text: l('Delete'),
confirmMessage: function (data) {
return l('BookDeletionConfirmationMessage', data.record.name);
},
action: function (data) {
aBPBookStore.book
.delete(data.record.id)
.then(function () {
abp.notify.info(l('SuccessfullyDeleted'));
dataTable.ajax.reload();
});
}
}
confirmMessage
选项用于在执行action
之前询问确认问题。aBPBookStore.book.delete()
方法向JavaScript代理功能发出AJAX请求以删除一本书。abp.notify.info()
显示删除操作后的通知。en.json
在Acme.BookStore.Domain.Shared
项目中打开并添加以下翻译:
"BookDeletionConfirmationMessage": "Are you sure to delete the book {0}?",
"SuccessfullyDeleted": "Successfully deleted"
运行该应用程序,然后尝试删除一本书。