2016-10-12 84 views
0

我的目標是在多個視圖中修改模型。 由於有時我的模型有很多屬性,我想在多個視圖中修改它們。喜歡的東西:在多個視圖中編輯模型

第一頁編輯2個屬性,第二頁編輯其他3個屬性,...

模型是這樣的:

public class LoadViewModel 
{ 
    public int CurrentPage { get; set; } = -1; 
    public PageViewModel PageViewModel { get; set; } 
} 

public class PageViewModel 
{ 
    public string Param1 { get; set; } 
    public string Param2 { get; set; } 
    public int Param3 { get; set; } 
} 

我的索引頁上的圖看起來像這樣:

@model LoadViewModel 
@using(Ajax.BeginForm("Load", "Home", new AjaxOptions {UpdateTargetId = "page"}, new {lvm = Model})) 
{ 
    <div id="page"></div> 
    <input type="submit"/> 
} 

,這是我的行動:

public ActionResult Load(LoadViewModel lvm = null) 
{ 
    if (lvm == null) lvm = new LoadViewModel(); 
    lvm.CurrentPage += 1; 
    TempData["CurrentPage"] = TempData["CurrentPage"] == null ? 0 : (int)TempData["CurrentPage"] + 1; 
    if (!partialViewDict.ContainsKey((int) TempData["CurrentPage"])) 
     TempData["CurrentPage"] = 0; 
    return PartialView(partialViewDict[(int)TempData["CurrentPage"]], lvm); 
} 

頁是映射只是諧音:

private Dictionary<int, string> partialViewDict = new Dictionary<int, string> 
{ 
    {0, "Pages/_Page1"}, 
    {1, "Pages/_Page2"}, 
    {2, "Pages/_Page3"}, 
}; 

和設計是這樣的:

@using WebApplication1.Controllers 
@model LoadViewModel 
@{ 
    TempData["CurrentPage"] = 0; 
} 

@Html.DisplayNameFor(m => m.PageViewModel.Param1) 
@Html.EditorFor(m => m.PageViewModel.Param1) 

這是工作。切換到第2頁時,模型設置正確,但當按下submit時,Param1(我在Page1中設置)的值重置爲null,只有在當前部分中設置的值是正確的。

這是第2頁:

@using WebApplication1.Controllers 
@model LoadViewModel 
@{ 
    TempData["CurrentPage"] = 1; 
} 
@Html.DisplayNameFor(m => m.PageViewModel.Param2) 
@Html.EditorFor(m => m.PageViewModel.Param2) 

當添加一個@Html.HiddenFor(m => m.PageViewModel.Param1)到部分,該值仍然設置。但我不想將這些值重新設置。我不想爲之前視圖中的所有屬性添加@Html.HiddenFor。如何避免在沒有爲所有未列出的屬性添加@Html.HiddenFor時觸及submit而重置值?還是有其他可能性來抓住我的目標?

回答

1

這裏有兩個部分,首先是帖子本身,然後對它進行驗證,爲此,每個步驟都應該有自己的視圖模型,只包含它應該修改的屬性,這樣可以添加所有的驗證你所需要的,而不會導致其他步驟失敗,最後,你會將所有這些數據合併到你的實體類或其他任何類型的數據庫中。他從每一步數據。 POST後唯一存在的數據是發佈的數據和會話中的任何數據(包括TempData)。你總是可以創建一堆隱藏的字段來存儲前面步驟中的數據,但這可能會有點麻煩。最有可能的是,你只想使用會話。

TempData基本上是Session的專門實例,所以您使用的並不重要。使用TempData時,您需要記住爲每個步驟設置的每個鍵調用TempData.Keep(),否則您將在下一個請求中丟失先前的步驟。 Session會在整個會話期間保留它們,但您應該記得在Session.Remove()的末尾刪除密鑰。

+0

嗯..所以也許創建一個viewmodel的每一步,然後映射到一個,如果最後一步被提交? (如果最後一步被提交,我只能將它們保存到數據庫中) - 如果有兩個人在運行它,它們不會覆蓋另一個用戶的TempData-Object? –

+0

沒有。 'Session' /'TempData'特定於客戶端。客戶端上設置了一個cookie,用於唯一標識其會話數據。 –

+0

mhh好吧,你有一個想法,如果這可能是一個性能問題,存儲在這樣一個TempData的大viewmodel? (可能有50個大字符串的屬性)。所以我可以在提交時將頁面的視圖模型映射到大視圖模型(例如AutoMapper),當用戶完成所有事情時可以將其存儲到數據庫中。這會是一個好的程序嗎? –

0

你在.cshtml中使用@using(Html.BeginForm())嗎?

不幸的是,這是MVC。 MVC是無狀態的,這意味着如果你不渲染它,那麼你就會鬆散它:(

如果你使用模型綁定和腳手架,那麼你可以節省一些時間和工作,但最終它會是同樣的解決方案。

+0

但是,必須有任何解決方案才能在多個視圖中修改模型!?否則,它似乎真的是靜態的..我的目標是建立一個安裝流程,讓用戶可以初始化和配置應用程序(在安裝操作系統之後就可以像windows一樣) - 而且不必滾動ironman(226公里)。不,我已經在使用'Ajax.BeginForm()'。用'Html.BeginForm()'這是不可能的 –

+0

小挑剔,但只是想澄清一下:HTTP是無狀態的。實際上MVC不是,它支持會話的概念,它增加了狀態。但是,假設會話未被使用,則請求將是「無狀態的」。 –