我在视图@Html.Action("office_holders_Test")
中有一个操作方法,在控制器类中我有以下方法,
我试图循环遍历每个办公室持有人的foreach
循环中的项目并添加到办公室持有人视图,但在循环第一项后我的代码中此功能仅返回我在officeholder局部视图中的第一个办公室持有人
public ActionResult office_holders_Test()
{
int Application_id = Convert.ToInt32(TempData["Application_id"]);
if (Application_id != 0)
{
var office_holders = Applicant_Service.GetOfficeHolderBy_Application_Id(Application_id);
DisplayDropdownList();
foreach (var OfficeHolder in office_holders)
{
return PartialView("../Applicant/OfficeHolderEntryEditor", OfficeHolder);
}
else
{
return PartialView("../Applicant/OfficeHolderEntryEditor", new tr_office_holders());
}
return PartialView("../Applicant/OfficeHolderEntryEditor")
}
}
答案 0 :(得分:0)
我建议使用的最佳选择是使用EditorTempate
。
您应该在View\Shared
中创建文件夹,并将其命名为EditorTemplates
。
在此文件夹中,创建与模型类同名的视图(例如tr_office_holders.cshtml
)。
此视图应包含一个项目的html和starns:
@model YourApplicationModelNamespace.tr_office_holders
有一个问题 - 您无法调用EditorTemplate
来收集Contoller ,这就是我建议您创建扩展方法的原因:
public static class ContollerExtensions
{
/// <summary>
/// Render partial method (Allows to render collections that implement IEnumerable interface)
/// </summary>
/// <param name="controller"></param>
/// <param name="viewName"></param>
/// <param name="model"></param>
/// <returns></returns>
public static string RenderPartial(this Controller controller, string viewName, object model)
{
var modelItems = model as IEnumerable<object>;
if (modelItems == null)
return controller.RenderPartialViewToString(viewName, model);
else
{
var result = String.Empty;
foreach (var modelItem in modelItems)
{
result += controller.RenderPartialViewToString(viewName, modelItem);
}
return result;
}
}
/// <summary>
/// Internal method that renders view and returning string
/// </summary>
/// <param name="controller"></param>
/// <param name="viewName"></param>
/// <param name="model"></param>
/// <returns></returns>
private static string RenderPartialViewToString(this Controller controller, string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
{
viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
}
controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
}
你可以在你的控制器中调用这个:
public ActionResult office_holders_Test()
{
int Application_id = Convert.ToInt32(TempData["Application_id"]);
if (Application_id != 0)
{
var office_holders = Applicant_Service.GetOfficeHolderBy_Application_Id(Application_id);
DisplayDropdownList();
this.RenderPartial("EditorTemplates/tr_office_holders", office_holders);
}
else
{
return this.RenderPartial("EditorTemplates/tr_office_holders", new tr_office_holders());
}
}
请注意,现在渲染一个元素或集合没有区别。
答案 1 :(得分:0)
所以听起来你想在视图中通过循环显示集合中的项目?你最好使用编辑器模板而不是部分视图。 MVC在显示和编辑器模板中有一些很好的功能,用于处理集合,您可以利用它们。我写了一篇关于using Display Templates的文章,你可能觉得它很有用。
我无法判断您的部分内容是否有任何表单输入,因此无法建议是使用编辑器还是显示模板。经验法则是,如果您显示只读标记,请使用“显示模板”。如果要为用户交互提供表单控件,请使用编辑器模板。你把你称为编辑,所以我们将继续这样做。
我将显示标记的业务与整理数据的业务分开。因此,您的控制器仅关注创建模型而不关注要呈现的模板。我们将把这个考虑留在视图中。为页面添加ViewModel,您将添加办公室持有者。我们称之为OfficeHoldersTestViewModel
:
public class OfficeHoldersTestViewModel
{
public IEnumerable<OfficeHolder> OfficeHolders { get; set; }
}
您的控制器操作现在只需要创建其中一个并填充办公室持有人:
public ActionResult office_holders_Test()
{
int Application_id = Convert.ToInt32(TempData["Application_id"]);
var model = new OfficeHoldersTestViewModel { OfficeHolders = new List<OfficeHolder>() };
if (Application_id != 0)
{
var office_holders = Applicant_Service.GetOfficeHolderBy_Application_Id(Application_id);
model.OfficeHolders = office_holders;
}
return View(model);
}
接下来,在名为OfficeHolder.cshtml的Views/Shared/EditorTemplates
中创建一个编辑模板,并将model
属性设置为OfficeHolder
类:
@model OfficeHolder
<!-- markup for an Office Holder goes here -->
最后,在您的主视图中,将model
设置为OfficeHoldersTestViewModel
,然后使用EditorFor
扩展程序方式显示您的办公室持有人:
@model OfficeHoldersTestViewModel
<div class="row">
<div class="col-xs-12">
@Html.EditorFor(m => m.OfficeHolders)
</div>
</div>
这个扩展方法的好处在于它适用于集合以及单个对象。在这种情况下,它将使用您为单个Office Holder创建的模板,并将其应用于集合中的每个项目,将它们呈现在另一个项目之下。
进一步阅读using Display Templates,您可能会觉得有用。
答案 2 :(得分:0)
你只看到第一个局部视图的原因是你的代码在foreach循环中有一个返回,它停止了代码的执行。
您必须只返回一个视图,您可以创建另一个局部视图并传递office_holders
列表,并在视图内部进行for循环:
public ActionResult office_holders_Test()
{
int Application_id = Convert.ToInt32(TempData["Application_id"]);
if (Application_id != 0)
{
var office_holders = Applicant_Service.GetOfficeHolderBy_Application_Id(Application_id);
DisplayDropdownList();
return PartialView("OfficeHolderEntryList", office_holders)
}
return PartialView("OfficeHolderEntryList")
}
视图:OfficeHolderEntryList.cshtml
@foreach (var officeHolder in Model)
{
Html.RenderPartial("OfficeHolderEntryEditor",officeHolder);
}