使用ASP.NET Core和Sircl构建丰富的Web应用程序——第4部分

目录

介绍

联系人管理器

更改为使用模态

添加Sircl支持

添加模态

不是Bootstrap的粉丝?

链接到模态

服务器端处理

结论


介绍

在本系列中,我们将了解如何仅使用ASP.NET CoreSircl轻松构建出色的交互式Web应用程序(通常需要大量JavaScript代码或用JavaScript框架编写的应用程序):

在关于ASP.NET CoreSircl的系列的第4部分中,我们将看到支持Bootstrap 模态是多么容易。Bootstrap是用于开发(响应式)网站的最流行的CSS框架之一。它还标配ASP.NETASP.NET Core项目模板。

联系人管理器

但首先要做的事情。如果我们想向Web应用程序添加一个模态,我们首先必须有一个应用程序......在对Sircl做任何事情之前,我们将创建一个简单的联系人管理器应用程序,我们可以在其中添加和编辑联系人。

联系人管理器应用程序包含2个页面:联系人列表和详细信息页面。目的是演示Bootstrap模态,我没有费心在下面放置一个数据库:de数据存储在静态变量中。

下面是de控制器的样子:

public class HomeController : Controller
{
  [HttpGet]
  public IActionResult Index()
  {
    var model = new IndexModel()
    {
      Items = DataContext.Contacts.Values
          .OrderBy(c => c.FirstName).ThenBy(c => c.LastName)
          .ToList()
    };
    return View(model);
  }

  [HttpGet]
  public IActionResult New()
  {
    var model = new EditModel()
    {
      Item = new Contact() { Id= DataContext.Contacts.Values.Max(c => c.Id) + 1 }
    };
    return EditView(model);
  }

  [HttpGet]
  public IActionResult Edit(int id)
  {
    var model = new EditModel() { Item = DataContext.Contacts[id] };
    return EditView(model);
  }

  [HttpPost]
  public IActionResult Save(EditModel model)
  {
    if (ModelState.IsValid)
    {
      DataContext.Contacts[model.Item.Id] = model.Item;
                       
      return RedirectToAction("Index");
    }

    return EditView(model);
  }

  [NonAction]
  private IActionResult EditView(EditModel model)
  {
    model.Countries = ISO3166.Country.List
        .OrderBy(c => c.Name)
        .Select(c => new SelectListItem(c.Name, c.TwoLetterCode));
    return View("Edit", model);
  }
}

这相当简单。Index方法返回一个页面,其中所有联系人都按名称排序。不支持分页、过滤、搜索或其他排序。

可以调用New方法来创建新联系人。它为新联系人创建EditModel并返回Edit视图。

Edit方法还返回Edit视图,但针对给定的(现有)联系人。

Save方法获取EditModel。如果模型有效,则保存联系人并重定向到索引操作。

EditView方法是一种帮助程序方法,用于确保在呈现编辑视图之前将国家/地区列表加载到模型中。为了获得国家/地区列表,我使用了Jørn Schou-RodeNuGet Gallery | ISO3166 1.0.4)的ISO3166 nuget

Index视图也非常简单:

@model IndexModel

<h1>Contacts</h1>
<a asp-action="New">Create a new contact</a>

<table class="table">
  <thead>
    <tr>
      <th>Id</th>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
    @foreach (var item in Model.Items)
    {
      <tr>
        <td>@item.Id</td>
        <td><a asp-action="Edit" asp-route-id="@item.Id">@item.FirstName</a></td>
        <td><a asp-action="Edit" asp-route-id="@item.Id">@item.LastName</a></td>
        <td><a asp-action="Edit" asp-route-id="@item.Id">@item.Email</a></td>
      </tr>
    }
  </tbody>
</table>

“Index”页面呈现一个表格,其中每个联系人都有一行,其中大多数单元格都链接到编辑操作。

用于创建新联系人或编辑现有联系人的编辑视图由于各种字段和Bootstrap样式而稍长一些:

@model EditModel

<form asp-action="Save" method="post">
  <input asp-for="Item.Id" type="hidden"/>

  <h1>Contact</h1>

  <div asp-validation-summary="All" class="alert alert-danger mb-3">
    <strong>Following errors have occured:</strong>
  </div>

  <div class="mb-3">
    <label asp-for="Item.FirstName" class="form-label">First name:</label>
    <input asp-for="Item.FirstName" class="form-control">
    <span asp-validation-for="Item.FirstName"></span>
  </div>

  <div class="mb-3">
    <label asp-for="Item.LastName" class="form-label">Last name:</label>
    <input asp-for="Item.LastName" class="form-control">
    <span asp-validation-for="Item.LastName"></span>
  </div>

  <div class="mb-3">
    <label asp-for="Item.Email" class="form-label">Email:</label>
    <input asp-for="Item.Email" class="form-control">
    <span asp-validation-for="Item.Email"></span>
  </div>

  <div class="mb-3">
    <label asp-for="Item.CountryCode" class="form-label">Country:</label>
    <select asp-for="Item.CountryCode" asp-items="Model.Countries" class="form-control">
        @if (Model.Item.CountryCode == null) { <option></option> }
    </select>
    <span asp-validation-for="Item.CountryCode"></span>
  </div>

  <button type="submit" class="btn btn-primary">Save</button>

</form>

这里又没什么特别的:使用post方法提交到 Save 操作的表单。联系人ID的隐藏字段、其他联系人属性的字段和标签以及提交按钮。

我还在顶部添加了验证摘要。

这就是联系人管理器。如果要查看Contact类定义或其他代码部分,请查看本文附件中的源代码。

或者更好的是,下载代码并运行它。本文的代码是我们到目前为止构建的,没有Bootstrap模态:之前的情况!

更改为使用模态

到目前为止,该应用程序有2个页面,当我们添加和编辑联系人时,浏览器会在它们之间来回导航。

假设我们希望停留在索引页面上,并在对话框中以Bootstrap模式呈现编辑页面。留在索引页面上,用户会更加专注,管理联系人会感觉不那么破坏性

所以让我们去吧!

添加Sircl支持

如前所述,Bootstrap支持是开箱即用的,包含在ASP.NET模板中。不过,我们仍然需要添加Sircl支持。为此,请在_Layout.cshtml模板中添加以下行,添加head部分的末尾:

<link href="https://cdn.jsdelivr.net/npm/sircl@2.4.4/sircl-bundled.min.css" rel="stylesheet" />

在正文末尾,添加以下行:

<script src="https://cdn.jsdelivr.net/npm/sircl@2.4.4/sircl-bundled.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sircl@2.4.4/sircl-bootstrap5.min.js"></script>

Sircl javascript引用必须放在包含jQuery之后。其余的,您可以按照所需的方式组织文件。最佳做法是将样式放在顶部,将脚本放在底部,但这不是必需的。

请注意,我们包含了2个脚本:Sircl捆绑包Sircl Bootstrap 5扩展。后者提供对Bootstrap组件的支持,例如模态、折叠和选项卡。

如果你下载了代码,你会注意到我已经在_Layout.cshtml文件中添加了对Sircl的引用。

添加模态

我们现在可以添加模态。您可以从Bootstrap站点复制示例代码并进行调整,也可以复制以下代码:

<div class="modal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Contact</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div id="contactmodal" class="modal-body target">
        (Content comes here)
      </div>
    </div>
  </div>
</div>

此代码表示Bootstrap模式。我们已经将标题设置为“Contact”,并删除了模态体元素的内容。

更重要的是我们添加了什么:我们在modal-body元素中添加了一个id “contactmodal,并且我们还在其中添加了target类。稍后会详细介绍这些。

此代码必须追加到Index.cshtml文件(或_Layout.cshtml文件),因为当用户位于索引页上时,它必须存在。

不是Bootstrap的粉丝?

除了使用Bootstrap模式之外,您还可以使用本机HTML5对话框。只需将上述模态代码替换为以下单个元素:

<dialog id="contactmodal" class="dialog-modal target"></dialog>

目前不支持其他模式或对话框,但Sircl是可扩展的,您可以自己添加支持。您甚至可以为Sircl项目做出贡献。我很乐意帮忙!

链接到模态

接下来,我们需要指定单击联系人应在模态中打开编辑表单。

使用Sircl,这真的很容易:我们只需将modal-body元素声明为超链接的目标,如下所示:

<a href="/Home/Edit/1" target="#contactmodal">Gerald</a>

超链接的目标包含一个CSS选择器,该选择器指向应在其中编写此链接响应的元素。它可以是任何有效的CSS选择器(包括相对的CSS选择器),因此与其使用id,您还可以编写target=".modal .target",但如果您定义多个模态,它可能会变得混乱。

虽然Sircl具有拦截调用并使其成为Ajax调用以检索#contactmodal元素内容的魔力,但SirclBootstrap扩展具有在收到内容后立即显示模态的魔力。每当SirclBootstrap模态中加载新内容时,Sircl Bootstrap扩展都会显示此模态。

完整的Index视图现在是:

@model IndexModel

<h1>Contacts</h1>
<a asp-action="New" target="#contactmodal">Create a new contact</a>

<table class="table">
  <thead>
    <tr>
      <th>Id</th>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
    @foreach (var item in Model.Items)
    {
      <tr>
        <td>@item.Id</td>
        <td><a asp-action="Edit" asp-route-id="@item.Id" target="#contactmodal">@item.FirstName</a></td>
        <td><a asp-action="Edit" asp-route-id="@item.Id" target="#contactmodal">@item.LastName</a></td>
        <td><a asp-action="Edit" asp-route-id="@item.Id" target="#contactmodal">@item.Email</a></td>
      </tr>
    }
  </tbody>
</table>

<div class="modal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Contact</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div id="contactmodal" class="modal-body target">
        (Content comes here)
      </div>
    </div>
  </div>
</div>

这就是视图。在编辑视图中无需进行任何更改。

服务器端处理

对于我们的控制器,我们只需要很少的更改。

首先,在EditView方法中,我们应该返回一个PartialView而不是一个View,因为我们不希望在模态中呈现整个页面(包括页眉和页脚以及导航菜单)。通过返回PartialView,我们只渲染视图本身,而没有布局模板,这正是我们想要的。

在本系列的第2部分中,我们还看到,还可以在_Layout.cshtml中以更通用的方式执行此操作。

因此,EditView方法现在变为:

[NonAction]
private IActionResult EditView(EditModel model)
{
    model.Countries = ISO3166.Country.List
        .OrderBy(c => c.Name)
        .Select(c => new SelectListItem(c.Name, c.TwoLetterCode));
    return PartialView("Edit", model);
}

然后,在保存联系人时,我们不想重定向到索引页面,因为我们已经在该页面上。相反,我们只想关闭模态。这可以通过返回NoContent()来完成。

如果我们更改或创建了联系人,我们还希望重新加载索引页面。我们可以通过返回一个响应标头来要求Sircl重新加载页面。

完整的Save方法现在已成为:

[HttpPost]
public IActionResult Save(EditModel model)
{
    if (ModelState.IsValid)
    {
        DataContext.Contacts[model.Item.Id] = model.Item;

        Response.Headers["X-Sircl-History"] = "reload";
        return NoContent();
    }

    return EditView(model);
}

控制器的所有其他方法保持不变。

请注意,当保存失败(ModelState无效)时,将再次呈现编辑视图(可能带有验证消息)。然后,Save 操作的响应仍呈现在modal-body中,因为该元素已通过target类标记为目标。

结论

如此示例所示,使用Sircl将多页Web应用程序转换为具有模态的单页应用程序就像轻而易举一样简单。

我们基本上只是将链接的目标设置为引用模态来渲染链接,并让控制器正确地响应新情况......

在下一篇文章中,我们将介绍Web应用程序中模态(或对话框)的另一个用例:在表单中使用模态来编辑部分表单数据的情况。

同时,请查看以下方面的更多Bootstrap支持功能:Sircl - Bootstrap support

https://www.codeproject.com/Articles/5381910/Build-Rich-Web-Apps-with-ASP-NET-Core-and-Sircl-5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值