【发布时间】:2019-07-22 19:26:15
【问题描述】:
我有一个 CSHTML 页面,但我无法找到构建我的请求流的最佳方式,以及保持 ViewModel 中的内容与 View 中显示的内容的持久性。
我使用 ASP.NET Web 服务作为 API 将网站连接到数据库。这是我的控制器在调用视图之前填充 ViewModel 的方式:
[AllowAnonymous]
[Route("company/sites")]
public async Task<IActionResult> CompanySites()
{
var client = _clientFactory.CreateClient("API");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", HttpContext.Request.Cookies[Startup._tokenCookieName]);
CompanyAccount user = JsonConvert.DeserializeObject<CompanyAccount>(HttpContext.Request.Cookies[Startup._companyInfoCookieName]);
if (user == null)
{
return RedirectToAction("Index", "Company");
}
CompanySitesViewModel viewModel = new CompanySitesViewModel ();
viewModel.LoggedInCompanyId = user.CompanyId;
// Populate viewModel...
return View(viewModel);
}
视图模型:
public class CompanySitesViewModel
{
public List<CompanyDTO> AdministratedCompanies { get; set; }
public CompanySitesViewModel ()
{
AdministratedCompanies = new List<CompanyDTO>();
}
}
这是我从 View 中的 ViewModel 访问数据的地方之一:
...
@if (Model.AdministratedCompanies.Count > 0)
{
<div class="list-group list-group-flush">
@for (int i = 0; i < Model.AdministratedCompanies.Count; i++)
{
<button class="list-group-item">
<div>
<h6>@Model.AdministratedCompanies[i].CompanyName</h6>
@if (@Model.AdministratedCompanies[i].CompanyCnpj != null)
{
<span><small class="text-muted">@@Model.AdministratedCompanies[i].CompanyCnpj</small></span>
}
</div>
</button>
}
</div>
}
...
当我想操作此列表中显示的数据时,我的问题就开始了。例如,我想从AdministratedCompanies 中删除一家公司。我目前正在直接对 API 进行 Ajax 调用,并在收到成功时强制刷新页面,以便在没有删除公司的情况下更新视图。
这是 Ajax 调用:
function deleteCurrentSite() {
if (currentCompanyIdToDelete != null) {
$.ajax({
url: "@Startup._apiConnectionString" + "sites/" + currentCompanyIdToDelete ,
type: "DELETE",
success: function (e) {
showAlert('Company deleted. Refreshing page...', true);
// Has to reload page to refresh site list
document.location.reload(true);
},
error: function (e) {
showAlert('Error deleting company.', false);
},
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Bearer " + '@Model.Token');
}
});
return false;
}
}
我有 React 开发背景,只需更改 state 并更新视图就非常容易,而且由于更改而不得不重新加载整个页面似乎非常不理想。
我有一些想法可以解决这个问题:
- 找到被删除公司的div,手动删除。不是最优的,当我想添加一个公司并且必须创建和附加组件时甚至更少。
- 让控制器存储 ViewModel 并让 Ajax 调用将我要删除的 ID 发送到控制器,然后控制器管理 API 调用。但据我发现,如果我使用
RedirectToAction或在删除后再次调用视图,页面仍然会刷新(尽管这似乎是让 Ajax 调用 API 的更好方法)。 - 找到了对该库 BeginCollectionItem 的一些引用,以在 View 和 ViewModel 之间创建更动态的绑定,但当我看到它在 7 年前更新时,我没有进一步调查。
那么在 View 和 ViewModel 之间创建动态绑定(包括 CRUD 操作和发生更改时重绘列表)的最佳方法是什么?
【问题讨论】:
-
您可以从控制器方法返回 JSON,然后 javascript 将处理响应数据并相应地更新页面。那时您已经将视图和数据分开了......尽管控制器可以更新数据,而 javascript 可以更新视图。
-
@pcalkins 这需要我操作 HTML 追加和删除 div,对吧?我总是觉得这样做是错误的,我认为 CSHTML 语法和 HTML 助手会有更好的方法。
-
如果您不想返回 JSON,您只需保留这些方法不变,并让 javascript 使用另一个 .cshtml 文件更新主 DIV。 (只是没有页眉/页脚的主要副本。)它将绑定到同一个控制器。我以前做过这个,只是在名称前加上“jq_”:“jq_pagename.cshtml”所以javascript用jq_页面更新主div。使用 partials,以便对部分的更新同时更新 main 和 jq_ 版本。
标签: asp.net ajax asp.net-mvc