展示页面--图书列表页面
本地化
开始的UI开发之前,我们首先要准备本地化的文本(这是你通常在开发应用程序时需要做的).本地化文本在前端页面会常用。
本地化文本位于 Acme.BookStore.Domain.Shared
项目的 Localization/BookStore
文件夹下:
打开 en.json
(英文翻译)文件并更改内容,如下所示:
{"Culture": "en","Texts": {"Menu:Home": "Home","Welcome": "Welcome","LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io.","Menu:BookStore": "Book Store","Menu:Books": "Books","Actions": "Actions","Close": "Close","Delete": "Delete","Edit": "Edit","PublishDate": "Publish date","NewBook": "New book","Name": "Name","Type": "Type","Price": "Price","CreationTime": "Creation time","AreYouSure": "Are you sure?","AreYouSureToDelete": "Are you sure you want to delete this item?","Enum:BookType.Undefined": "Undefined","Enum:BookType.Adventure": "Adventure","Enum:BookType.Biography": "Biography","Enum:BookType.Dystopia": "Dystopia","Enum:BookType.Fantastic": "Fantastic","Enum:BookType.Horror": "Horror","Enum:BookType.Science": "Science","Enum:BookType.ScienceFiction": "Science fiction","Enum:BookType.Poetry": "Poetry"}
}
简体中文翻译请打开
zh-Hans.json
文件 ,并将"Texts"对象中对应的值替换为中文.
- 本地化关键字名称是任意的. 你可以设置任何名称. 对于特定的文本类型,我们更喜欢遵循一些约定:
- 为按钮项添加
Menu:
前缀. - 使用
Enum:<enum-type>:<enum-name>
或<enum-type>.<enum-name>
或<enum-name>
命名约定来本地化枚举成员. 当您这样做时ABP可以在某些适当的情况下自动将枚举本地化.
- 为按钮项添加
如果未在本地化文件中定义文本,则文本将回退到本地化键(ASP.NET Core的标准行为).
创建图书页面
是时候创建可见的和可用的东西了! 我们将使用微软推荐的Razor Pages UI,而不是经典的MVC.
在 Acme.BookStore.Web
项目的 Pages
文件夹下创建一个名为新的 Books
的文件夹. 然后在文件夹右键选择 添加 > Razor Page 菜单. 输入名称 Index
:
打开 Index.cshtml
并把内容修改成下面这样:
@page
@using Acme.BookStore.Web.Pages.Books
@model IndexModel<h2>Books</h2>
@page
这行代码声明这是一个Razor Page。Razor Pages 是一种ASP.NET Core的功能,用于简化基于页面的Web应用程序的开发。
@page
指令使得这个文件成为一个处理HTTP请求的页面。
@using Acme.BookStore.Web.Pages.Books
这行代码引入了
Acme.BookStore.Web.Pages.Books
命名空间。使用@using
指令可以导入命名空间,使得在页面中可以直接使用该命名空间下的类和方法。
@model IndexModel
这行代码指定了这个页面使用的模型类是
IndexModel
。IndexModel
是一个后台代码类,通常位于Index.cshtml.cs
文件中,包含了处理页面数据和操作的逻辑。在Razor Page中,模型类通常派生自PageModel
类。
Index.cshtml.cs
内容应该是:
using Microsoft.AspNetCore.Mvc.RazorPages;namespace Acme.BookStore.Web.Pages.Books
{public class IndexModel : PageModel{public void OnGet(){}}
}
将图书页面添加到主菜单
打开 Menus
文件夹中的 BookStoreMenuContributor
类,在 ConfigureMainMenuAsync
方法的底部添加如下代码:
context.Menu.AddItem(new ApplicationMenuItem("BooksStore",l["Menu:BookStore"],icon: "fa fa-book").AddItem(new ApplicationMenuItem("BooksStore.Books",l["Menu:Books"],url: "/Books"))
);
运行项目,使用用户名 admin
和密码 1q2w3E*
登录到应用程序. 看到新菜单项已添加到菜单栏:
图书列表
Index.cshtml
将 Pages/Book/Index.cshtml
改成下面的样子:
@page
@using Acme.BookStore.Localization
@using Acme.BookStore.Web.Pages.Books
@using Microsoft.Extensions.Localization
@model IndexModel
@inject IStringLocalizer<BookStoreResource> L
@section scripts
{<abp-script src="/Pages/Books/Index.js" />
}
<abp-card><abp-card-header><h2>@L["Books"]</h2></abp-card-header><abp-card-body><abp-table striped-rows="true" id="BooksTable"></abp-table></abp-card-body>
</abp-card>
abp-script
tag helper用于将外部的 脚本 添加到页面中.它比标准的script
标签多了很多额外的功能.它可以处理 最小化和 版本.查看捆绑 & 压缩文档获取更多信息.abp-card
和abp-table
是为Twitter Bootstrap的card component封装的 tag helpers.ABP中有很多tag helpers,可以很方便的使用大多数bootstrap组件.你也可以使用原生的HTML标签代替tag helpers.使用tag helper可以通过智能提示和编译时类型检查减少HTML代码并防止错误.查看tag helpers 文档.
Index.js
在 Pages/Books/
文件夹中创建 index.js
文件
js的内容:
$(function () {var l = abp.localization.getResource('BookStore');var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({serverSide: true,paging: true,order: [[1, "asc"]],searching: false,scrollX: true,ajax: abp.libs.datatables.createAjax(acme.bookStore.books.book.getList),columnDefs: [{title: l('Name'),data: "name"},{title: l('Type'),data: "type",render: function (data) {return l('Enum:BookType:' + data);}},{title: l('PublishDate'),data: "publishDate",render: function (data) {return luxon.DateTime.fromISO(data, {locale: abp.localization.currentCulture.name}).toLocaleString();}},{title: l('Price'),data: "price"},{title: l('CreationTime'), data: "creationTime",render: function (data) {return luxon.DateTime.fromISO(data, {locale: abp.localization.currentCulture.name}).toLocaleString(luxon.DateTime.DATETIME_SHORT);}}]}));
});
abp.localization.getResource
获取一个函数,该函数用于使用服务器端定义的相同JSON文件对文本进行本地化. 通过这种方式你可以与客户端共享本地化值.abp.libs.datatables.normalizeConfiguration
是一个辅助方法.不是必须的, 但是它通过为缺省的选项提供约定的值来简化Datatables配置.abp.libs.datatables.createAjax
是另一个辅助方法,用来适配ABP的动态JavaScript API代理和Datatable期望的参数格式.acme.bookStore.books.book.getList
是动态JavaScript代理函数(上面已经介绍过了)- luxon 库也是该解决方案中预先配置的标准库,你可以轻松地执行日期/时间操作.
最终的效果图
出现的问题
菜单项无法点击
菜单项无法点击,然后 看网页的控制台,各种找不到,这是我们缺少一个lib包
Could not find the bundle file '/libs/abp/luxon/abp.luxon.js' for the bundle 'LeptonXLite.Global'!
VM52:1 Could not find the bundle file '/libs/timeago/jquery.timeago.js' for the bundle 'LeptonXLite.Global'!
可以直接去我得资源中去找。