2011-07-20 29 views
0

這是我的情況:在視圖模型從視圖返回一個列表<E>

我有這樣的視圖模型:

public class ViewModel 
{ 
    public DateTime someDate { get; set; } 
    public String someString { get; set; } 
    public List<E> someList { get; set; } 
} 

我所要做的就是在視圖設置日期,寫一些文本,然後從E的列表中選擇任意數量的E.在操作中返回的ViewModel必須包含日期,文本幷包含所選項目的列表。

我需要知道的是如何處理所述列表。我如何將每個選定的項目添加到模型的列表中。我正在考慮爲E添加一個屬性public bool selected,然後發送所有項並在服務器上過濾所選項,但我寧願不發送所有數據,因爲列表可能非常大。

我使用的剃刀和JQUERY AJAX的MVC3所有我的表單帖子。

如果我不清楚自己,請告訴我。

謝謝。

回答

6

以下是您可以用來實現此目的的一種技術。

讓我們先從視圖模型:

public class ViewModel 
{ 
    public DateTime SomeDate { get; set; } 
    public string SomeString { get; set; } 
    public List<E> SomeList { get; set; } 
} 

public class E 
{ 
    public bool Selected { get; set; } 
    public string Foo { get; set; } 
    public string Bar { get; set; } 
} 

然後我們寫一些控制器來處理視圖的渲染和AJAX請求:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new ViewModel 
     { 
      SomeDate = DateTime.Now, 
      SomeString = "some text", 
      SomeList = Enumerable.Range(1, 7).Select(x => new E 
      { 
       Foo = "foo " + x, 
       Bar = "bar " + x 
      }).ToList() 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(ViewModel model) 
    { 
     // Here we will get our view model properly bound and 
     // the list will contain only the items that the user 
     // has selected (see below...) 

     // TODO: do some processing 

     return Content("Thanks for submitting this data", "text/plain"); 
    } 
} 

然後我們轉移到~/Views/Home/Index.cshtml視圖:

@model ViewModel 

@using (Html.BeginForm()) 
{ 
    <div> 
     @Html.LabelFor(x => x.SomeDate) 
     @Html.EditorFor(x => x.SomeDate) 
    </div> 

    <div> 
     @Html.LabelFor(x => x.SomeString) 
     @Html.EditorFor(x => x.SomeString) 
    </div> 

    <table> 
     <thead> 
      <tr> 
       <th></th> 
       <th>Foo</th> 
       <th>Bar</th> 
      </tr> 
     </thead> 
     <tbody> 
      @Html.EditorFor(x => x.SomeList) 
     </tbody> 
    </table> 

    <input type="submit" value="Send selected values to server using AJAX" /> 
} 

最後我們定義了一個的編輯器模板型(~/Views/Home/EditorTemplates/E.cshtml)將被渲染爲集合中的每個元素:

@{ 
    var index = Guid.NewGuid().ToString(); 
    var prefix = Regex.Replace(ViewData.TemplateInfo.HtmlFieldPrefix, @"\[\d+\]$", match => 
    { 
     return string.Format("[{0}]", index); 
    }); 
    ViewData.TemplateInfo.HtmlFieldPrefix = prefix; 
} 
<input type="hidden" name="SomeList.Index" value="@index" /> 
<tr> 
    <td> 
     @Html.DisplayFor(x => x.Foo) 
     @Html.HiddenFor(x => x.Foo) 
    </td> 
    <td> 
     @Html.DisplayFor(x => x.Bar) 
     @Html.HiddenFor(x => x.Bar) 
    </td> 
    <td> 
     @Html.CheckBoxFor(x => x.Selected) 
    </td> 
</tr> 

OK,所以在這個階段,我們還沒有編寫的JavaScript一部分,所以這應該表現爲一個普通的HTML表單,當它被提交時,它會將所有的值發送到服務器。

最後一部分是對錶單進行AJAXify並僅POST用戶在請求中選擇的記錄。因此,我們可以在一個單獨的JavaScript文件做到這一點:

$(function() { 
    $('form').submit(function() { 
     // we clone the original form and we will 
     // filter out the non-selected fields 
     var myForm = $(this).clone(false, false); 

     $('tr', myForm).each(function() { 
      var isSelected = $(':checkbox', this).is(':checked'); 
      if (!isSelected) { 
       $(this).remove(); 
      } 
     }); 

     $.ajax({ 
      url: this.action, 
      type: this.method, 
      data: myForm.serialize(), 
      success: function (result) { 
       alert(result); 
      } 
     }); 

     return false; 
    }); 
}); 

是好文章來處理動態列表,我會建議你following blog post

+0

感謝您的回覆......我正在嘗試您的代碼,但顯然當我序列化表單以使ajax調用List在服務器端代碼中出現空值時...所有其他值都是正確的,但是列表顯示爲空。任何想法可能是什麼問題? – AJC

+0

@AJC,這很奇怪,因爲這個代碼在我的機器上測試時工作。 –

+0

我檢查了代碼,它確實從列表中刪除了所有未檢查的項目,看起來好像列表沒有被序列化。我嘗試了沒有AJAX只是爲了看到問題仍然存在,列表在服務器中出現空。 – AJC

相關問題