@RenderPage とコントローラーのアクションの両方によって呼び出される部分ビューが 1 つあります。
これは、PageData[] でパラメーターを渡す @RenderPage を使用して別のビューから呼び出すコードです。
@foreach (var subTree in itemTree.SubTrees)
{
<li id ="@("LiOf" + subTree.Root.ID)" style = "margin-top: 0px">
@RenderPage("~/Areas/MFC/Views/Items/_SubItemsTree.cshtml", subTree, itemTreeViewModel, false, Request.RawUrl, showOpenAsTreeRoot)
</li>
}
ところで、この部分ビューは「treeNode」であるため、1 回の呼び出しで何度もレンダリングされます。
モデルと ViewBag でパラメーターを渡すコントローラーのアクションのコードを次に示します。特定のノードを更新する必要がある場合、このアクションが呼び出されます。
var fatherTree = ItemTree.ItemTreeOf(item.FatherID);
ViewBag.IsSubtreeRoot = true;
ViewBag.ReturnUrl = returnUrl;
ViewBag.ItemTreeViewModel = new ItemTreeViewModel(
view, fatherTree, whats, types,
showPopupOperationMenu: true, showMoveLeftRight: true, showMoveUpDown: true);
ViewBag.ShowOpenAsTreeRoot = true;
return View("~/Areas/MFC/Views/Items/_SubItemsTree.cshtml", fatherTree);
2 つのケースで適切に機能するために、レンダリングされるビューは次のようになります。
@model ItemTree
@using Martian.Areas.MFC.Models;
@{
var itemTree = (PageData[0] as ItemTree) ?? Model;
var itemTreeViewModel = PageData[1] ?? ViewBag.ItemTreeViewModel as ItemTreeViewModel;
var isSubtreeRoot = (bool) (PageData[2] ?? ViewBag.IsSubtreeRoot);
var returnUrl = PageData[3] ?? ViewBag.ReturnUrl as string;
var showOpenAsTreeRoot = (bool)(PageData[4] ?? ViewBag.ShowOpenAsTreeRoot);
そして、はい、それはうまく機能しますが、ぎこちなく見えます。@Html.RenderPartial ではなく @RenderPage によって呼び出されるように部分ビューのパックを転送する必要があり、何らかのアクションによって返される必要があるため、これは問題になります。それを行うより良い方法はありますか?ありがとう。
2013-01-19 面倒ですが実行可能な解決策は次のとおりです。
Controller.View に複数のパラメータを渡すことができれば、それを PageData[] として cshtml に渡すことができます。
ステップ 1. コントローラーからの呼び出しを変更します。
public ActionResult AjaxRemoveUser(int departmentID, int teamID, string userName, int udcTypeValue)
{
var team = _repMFC.ReadItemAt<Department>(teamID);
team.RemoveUser(udcTypeValue, userName);
return MFCView("AssignMembers/_AjaxTeam", _repMFC.ReadItemAt<Department>(departmentID), team, true);
}
ステップ 2. コントローラと の代わりに MFCController からコントローラを派生させます。MFCController は、何らかの理由で以前に設計されたクラスであり、すべてのコントローラーはそこから派生しています。
MFCController には、次のような MFCView() の本体があります。
public ActionResult MFCView(string ajaxViewName, params object[] list)
{
var ajaxViewPath = ((BuildManagerCompiledView) (ViewEngines.Engines.FindPartialView(ControllerContext, ajaxViewName).View)).ViewPath;
var viewModel = new MFCViewModel { AjaxViewPath = ajaxViewPath, PageData = list };
return View("~/Views/Shared/_MFCView.cshtml", viewModel);
}
ステップ 3. MFCViewModel:
public class MFCViewModel
{
public string AjaxViewPath;
public object[] PageData;
}
それは非常に明確で簡単です。
ステップ 4. ~/Views/Shared/_MFCView.cshtml
@model Martian.Areas.MFC.Models.MFCController.MFCViewModel
@{
@RenderPage(Model.AjaxViewPath, Model.PageData)
}
ステップ 5. ビュー AssignMembers/_AjaxTeam.cshtml: トピックの冒頭で説明したように、以前は次のように表示されていました。
var department = (PageData[0]??ViewBag.Department) as Department;
var team = (PageData[1]??ViewBag.Team) as Department;
var enableEditMembers = (bool)(PageData[2]??ViewBag.EnableEditMembers);
そして今、それは実際には次のとおりです。
var department = PageData[0] as Department;
var team = PageData[1] as Department;
var enableEditMembers = (bool) PageData[2];
これで、MFCView() に渡したパラメーターによって PageData が作成されます。
プロセスは面倒に見えますが、作業が完了したら、MFCView を使用して、必要な数のパラメーターを渡すことができます。ViewBag も、ViewData[] も、ViewModel もありません! 通常のメソッドを呼び出しているようです。