我有一个 MVC 3 页面,它返回一个用户响应列表,其中包含每个响应的名为“memo”(显示/添加备忘录)的部分视图。当我向响应添加备忘录时,它应该更新数据库和该响应的备忘录列表。它应该是通过ajax进行部分页面更新,它只影响部分视图“备忘录”。
包含“备忘录”的视图Response.chtml:
@using (Html.BeginForm("Response", "User", FormMethod.Post, new { id = "UserResponse" }))
{
.... code removed ....
@foreach (var response in Model)
{
<div class="qna"><input type="text" id=@response.responseId value="@response.ResponseText" />
<div>@Html.Partial("_memo", response.responseId)</div>
}
.....
部分页面“_memo.chtml”:
<div>add memo</div>
<ul id="memos">
@foreach (var memo in Model) {
<li>@memo.Text</li>
}
</ul>
<form method="post" id="memoForm"
action="@Url.Action("AddMemo")">
@Html.TextArea("Memo", new { rows = 5, cols = 50 })
<br />
<input type="submit" value="Add" />
</form>
用于查看用户/响应的控制器:
[HttpGet]
public ActionResult Response(id)
{
.....
return View(responses);
我刚开始使用上面的代码,需要帮助填补空白。
如果我将响应ID传递给局部视图,我该如何提取该响应的备忘录列表?它会涉及ajax吗? (而不是...... Partial("_memo", response.memos)
)
如何通过ajax调用更新局部视图。什么是客户端的ajax调用(示例代码)以及控制器的外观如何?当ajax调用成功时,如何更新列表备忘录div="memos"
以反映新备忘录?
来自Response的表单操作是否会与部分视图Memo的表单操作冲突?
答案 0 :(得分:2)
问题答案:
这是我目前正在处理的项目的修改示例:
需要遵循一些代码,所以这里有:
这是我的模特。职业规划表上有几个部分,其中一个部分是选择和更新能力的部分。 SelectCompetencies模型中包含一系列能力。用户将能够添加能力。当他们这样做时,它将被添加到数据库中,并将更新部分中的能力列表。
public class CareerPlanningFormViewModel
{
// code removed ...
public SelectCompetenciesModel SelectCompetencies { get; set; }
// code removed ...
}
public class SelectCompetenciesModel
{
public int CareerPlanningFormID { get; set; }
public IList<CompetencyModel> Competencies { get; set; }
public byte MaximumCompetenciesAllowed { get; set; }
}
public class CompetencyModel
{
public int CompetencyID { get; set; }
public int? CompetencyOptionID { get; set; }
public string ActionPlan { get; set; }
public IDictionary<int, string> CompetencyOptions { get; set; }
}
职业规划表的主要观点:/Views/CPF/CareerPlanningForm.cshtml
@model MyNamespace.Models.CareerPlanningForm.CareerPlanningFormViewModel
<link rel="stylesheet" href="@Url.Content("~/Content/CreateCPF.css")" />
@using (Html.BeginForm())
{
// other sections loaded here...
// code removed for brevity...
@Html.Partial("SelectCompetencies", Model.SelectCompetencies)
// other sections loaded here...
// code removed for brevity...
}
SelectCompetencies partial:/Views/CPF/SelectCompetencies.cshtml 用户将填写新的行动计划文本,然后单击添加能力按钮。 这将通过ajax发布到CPFController / NewCompetencyTemplate
@model MyNamespace.Models.CareerPlanningForm.SelectCompetenciesModel
@Html.HiddenFor(m => m.CareerPlanningFormID)
<h3>Select Competencies</h3>
<p class="guidance">
Select up to @Model.MaximumCompetenciesAllowed competencies to focus on improving.
</p>
<table id="CompetenciesTable">
<thead>
<tr>
<th>Competency</th>
<th>Action Plan:</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Competencies.Count(); i++)
{
@Html.EditorFor(m => m.Competencies[i])
}
</tbody>
<tfoot id="CompetenciesTableFooter" class="@(Model.Competencies.Count() < Model.MaximumCompetenciesAllowed ? "" : "hidden")">
<tr>
<td colspan="2">
@Html.TextArea("NewActionPlanText")
@Html.Button(ButtonType.Button, "Add Another Competency", "add", new { id = "AddCompetencyButton" })
</td>
</tr>
</tfoot>
</table>
@section script
{
<script>
jQuery(document).ready(function ($) {
var competenciesTableBody = $('#CompetenciesTable tbody'),
competenciesTableFooter = $('#CompetenciesTableFooter'),
addCompetencyButton = $('#AddCompetencyButton'),
newCompetencyTemplateUrl = '@Url.Content("~/CPF/NewCompetencyTemplate")',
count = competenciesTableBody.find('tr').length,
newActionPlanText = $('#NewActionPlanText'),
careerPlanningFormID = $('#CareerPlanningFormID');
addCompetencyButton.click(function () {
$.ajax({
url: newCompetencyTemplateUrl(),
type: 'POST',
data: {
careerPlanningFormID: careerPlanningFormID,
actionPlan: newActionPlanText,
itemCount: count
},
dataType: 'html',
success: function (data) {
var elements = $(data);
// other code removed here...
competenciesTableBody.append(elements);
// other code removed here...
}
});
});
});
</script>
}
查看/ CPF / EditorTemplates / CompetencyModel.cshtml
@model MyNamespace.Models.CareerPlanningForm.CompetencyModel
<tr class="competency">
<td>
@Html.DropDownListFor(m => m.CompetencyOptionID, new SelectList(Model.CompetencyOptions, "Key", "Value"), "Select competency...")
</td>
<td>
@Html.TextAreaFor(m => m.ActionPlan, new { @class = "competencyActionPlan" })
@Html.HiddenFor(m => m.CompetencyID)
</td>
</tr>
包含添加新能力的操作的控制器:/Controllers/CPFController.cs
这将调用CareerPlanningFormService以添加新的能力,并将返回NewCompetencyTemplate的部分视图,该视图将呈现新的能力
public class CPFController : Controller
{
private readonly ICareerPlanningFormService careerPlanningFormService;
public CPFController(ICareerPlanningFormService careerPlanningFormService)
{
this.careerPlanningFormService = careerPlanningFormService;
}
[HttpPost]
public PartialViewResult NewCompetencyTemplate(int careerPlanningFormID, int itemCount, string newActionPlanText)
{
var count = itemCount + 1;
// Even though we're only rendering a single item template, we use a list
// to trick MVC into generating fields with correctly indexed name attributes
// i.e. Competencies[1].ActionPlan
var model = new SelectCompetenciesModel
{
Competencies = Enumerable.Repeat<CompetencyModel>(null, count).ToList()
};
model.Competencies[count - 1] = this.careerPlanningFormService.BuildNewCompetencyModel(careerPlanningFormID, newActionPlanText);
return this.PartialView(model);
}
}
我的服务类:CareerPlanningFormService.cs
它处理业务逻辑并调用存储库以将项添加到数据库并返回新的CompetencyModel
public class CareerPlanningFormService : ICareerPlanningFormService
{
private readonly IMyRenamedRepository repository;
private readonly IPrincipal currentUser;
public CareerPlanningFormService(
IMyRenamedRepository repository,
IPrincipal currentUser)
{
this.repository = repository;
this.currentUser = currentUser;
}
public CompetencyModel BuildNewCompetencyModel(int careerPlanningFormID, string newActionPlanText)
{
var competency = new Competency
{
CareerPlanningFormID = careerPlanningFormID,
CompetencyOptionID = null,
ActionPlan = newActionPlanText
};
this.repository.Add(competency);
this.repository.Commit();
return new CompetencyModel
{
CompetencyID = competency.CompetencyID,
CompetencyOptionID = competency.CompetencyOptionID,
ActionPlan = competency.ActionPlan,
CompetencyOptions = this.GetCompetencyOptionsForCareerPlanningFormID(careerPlanningFormID)
};
}
}
现在,NewCompetencyTemplate的部分内容:Views / CPF / NewCompetencyTemplate.cshtml
这很简单,它只是渲染与上面相同的编辑器模板,用于集合中的最后一个能力(我们刚刚添加)
@model MyNamespace.Models.CareerPlanningForm.SelectCompetenciesViewModel
@Html.EditorFor(m => m.Competencies[Model.Competencies.Count() - 1])
当ajax调用成功时,它将从它调用的控制器操作方法接收到该部分返回。然后将其部分并将其附加到能力表主体
// snippet from ajax call above
competenciesTableBody.append(elements);
我希望这会有所帮助。如果您有任何其他问题,请与我们联系。
答案 1 :(得分:1)
虽然您可以通过返回包含更新内容的部分视图来解决问题,但您也可以考虑使用jQuery的加载方法。
查看here,特别是在&#34;加载页面片段&#34;部分。基本上你可以再次获得原始页面,jQuery将提取&#34;提取&#34;您想要的内容,只要它可以被选择器(例如div id)定位。
注意,此解决方案并不适用于所有情况,因为服务器的响应中会有冗余标记,因为您将丢弃其余页面内容并仅使用更新的部分。