2011-07-20 32 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

相关问题