目录
介绍
背景
使用代码
添加分页
样式化内容
兴趣点
介绍如第1部分所述,Index.cshtml视图在单个页面上显示数据库中的书籍。在本文中,我将添加对分页的支持,以便视图在一个页面上显示较少数量的书籍,并且用户可以从一个页面移动到另一个页面以查看整个目录。我还将使用Bootstrap设置内容样式。
背景在本文中,我们将熟悉一些用于构建BooksStore应用程序核心基础架构的技术,例如如何添加分页、如何使用标签助手、什么是局部视图以及如何使用它、如何创建HTML属性名格式与C#属性名格式之间的映射,如何用Bootstrap设置内容的样式等等。
使用代码 添加分页我们将使用以下代码向Home控制器中的Index方法添加一个参数:
public class HomeController : Controller
{
private IBooksStoreRepository repository;
public int PageSize = 3;
public HomeController(IBooksStoreRepository repo)
{
repository = repo;
}
public IActionResult Index(int bookPage = 1)
=> View(repository.Books
.OrderBy(b => b.BookID)
.Skip((bookPage - 1) * PageSize)
.Take(PageSize));
}
前面的代码:
- 该PageSize字段指定我们想要每页三本书。
- 我们获取Book对象,按主键(BookID)对它们进行排序,跳过当前页面开始之前出现的书籍,并获取PageSize字段指定的书籍数量。
我们可以使用查询字符串浏览图书目录。运行应用程序,我们将看到页面上现在显示了三本书:
如果我们想查看另一个页面,我们可以将查询字符串参数附加到URL的末尾,如下所示:
http://localhost:44333/?bookPage=2
我们需要在每个图书列表的底部渲染一些页面链接,以便客户可以在页面之间导航。为此,我们将创建一个标签助手,它为我们需要的链接生成HTML标记。
为了支持标签助手,我们将创建一个视图模型类,它专门用于在控制器和视图之间传递数据,方法是在BooksStore项目中创建一个Models/ViewModels文件夹,向其中添加一个名为PagingInfo.cs的类文件,并使用以下代码定义类:
using System;
namespace BooksStore.Models.ViewModels
{
public class PagingInfo
{
public int TotalItems { get; set; }
public int ItemsPerPage { get; set; }
public int CurrentPage { get; set; }
public int TotalPages =>
(int)Math.Ceiling((decimal)TotalItems / ItemsPerPage);
}
}
在前面的代码中,我们希望将有关可用页数、当前页和存储库中图书总数的信息传递给视图。
现在我们将在BooksStore项目中创建一个名为MyTagHelper的文件夹,并向其中添加一个名为MyPageLink.cs的类文件,其中包含以下代码:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using BooksStore.Models.ViewModels;
namespace BooksStore.MyTagHelper
{
[HtmlTargetElement("div", Attributes = "page-model")]
public class MyPageLink : TagHelper
{
private IUrlHelperFactory urlHelperFactory;
public MyPageLink(IUrlHelperFactory helperFactory)
{
urlHelperFactory = helperFactory;
}
[ViewContext]
[HtmlAttributeNotBound]
public ViewContext ViewContext { get; set; }
public PagingInfo PageModel { get; set; }
public string PageAction { get; set; }
public override void Process(TagHelperContext context,
TagHelperOutput output)
{
IUrlHelper urlHelper = urlHelperFactory.GetUrlHelper(ViewContext);
TagBuilder result = new TagBuilder("div");
for (int i = 1; i View(new BooksListViewModel
{
Books = repository.Books
.OrderBy(p => p.BookID)
.Skip((bookPage - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo
{
CurrentPage = bookPage,
ItemsPerPage = PageSize,
TotalItems = repository.Books.Count()
}
});
我们创建了包含分页信息的视图模型,更新了控制器以便将这些信息传递给视图。现在我们将更改@model指令以匹配新的模型视图类型并添加标签助手将处理以创建页面链接的HTML元素,如以下标记:
@model BooksStore.Models.ViewModels.BooksListViewModel
@foreach (var p in Model.Books)
{
@p.Title
@p.Description
@p.Genre
@p.Price.ToString("c")
}
因为页面链接仍然使用查询字符串将页面信息传递给服务器,例如http://localhost/?bookPage=2,我们可以在Startup类中添加一个新路由来改进URL,使用以下代码:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this
// for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
// old URL: http://localhost:44333/?bookPage=2
// new URL: https://localhost:44333/Books/2
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("pagination",
"Books/{bookPage}",
new { Controller = "Home", action = "Index" });
endpoints.MapDefaultControllerRoute();
});
SeedData.EnsurePopulated(app);
}
}
这是更改书籍分页的 URL 方案所需的唯一更改。运行应用程序并单击分页链接之一:
我们将使用Bootstrap来提供我们将应用于应用程序的CSS样式。在Visual Studio 2019中,我们可以在wwwroot/lib文件夹中找到Bootstrap:
Razor布局提供通用内容,因此不必在多个视图中重复。我们更改Views/Shared文件夹中的_Layout.cshtml文件,以在发送到浏览器的内容中包含Bootstrap CSS样式表,并定义一个通用标题,该标题将在整个BooksStore应用程序中使用,并带有以下标记:
BooksStore
BOOKS STORE
The BooksStore homepage helps you explore Earth's Biggest Bookstore
without ever leaving the comfort of your couch.
@RenderBody()
接下来,我们将在Views/Shared文件夹中添加一个名为BookTemplate.cshtml的Razor视图,并添加如下所示的标记:
@model Book
@Model.Title
@Model.Price.ToString("c")
@Model.Genre
@Model.Description
我们创建了一个局部视图,它是一个可以嵌入到另一个视图中的内容片段,就像一个模板。现在我们需要更新Views/Home文件夹中的Index.cshtml文件,以便它使用局部视图:
@model BooksStore.Models.ViewModels.BooksListViewModel
@foreach (var p in Model.Books)
{
}
我们需要在div元素上定义自定义属性来指定我们需要的类,这些属性对应于我们添加到标签助手类的属性,然后用于设置生成的a元素的样式。为此,我们将使用以下代码对MyPageLink类进行一些更改:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using BooksStore.Models.ViewModels;
namespace BooksStore.MyTagHelper
{
[HtmlTargetElement("div", Attributes = "page-model")]
public class MyPageLink : TagHelper
{
private IUrlHelperFactory urlHelperFactory;
public MyPageLink(IUrlHelperFactory helperFactory)
{
urlHelperFactory = helperFactory;
}
[ViewContext]
[HtmlAttributeNotBound]
public ViewContext ViewContext { get; set; }
public PagingInfo PageModel { get; set; }
public string PageAction { get; set; }
public bool PageClassesEnabled { get; set; } = false;
public string PageClass { get; set; }
public string PageClassNormal { get; set; }
public string PageClassSelected { get; set; }
public override void Process(TagHelperContext context,
TagHelperOutput output)
{
IUrlHelper urlHelper = urlHelperFactory.GetUrlHelper(ViewContext);
TagBuilder result = new TagBuilder("div");
for (int i = 1; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?