从View创建List <t>并使用表单POST到MVC控制器

时间:2016-06-21 23:00:23

标签: javascript c# asp.net-mvc viewmodel

背景
我正在研究客户的网站项目,我使用MVC来创建网站。我让EF使用SQLDB来存储数据。

我的WebApp配备了一个后台区域,用于管理/添加/更新Item等。

有问题的特定页面允许用户通过输入数据并单击表单上的“保存”来向数据库添加新的Item

Item有一些属性,所有这些属性都可以很好地添加到新行中。

Item还包含针对它声明的List<Appointment>(我将序列化这些并将它们保存在相应的列中)。

对象看起来像这样(为简洁起见,我删除了一些属性):

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Appointment> Appointments { get; set; }
    // Plus some other properties
}

public class Appointment
{
    public string Day { get; set; }
    public string From { get; set; }
    public string To { get; set; }
}

我已经设置了一个ViewModel,我正在练习所有通常的好习惯。它看起来像这样:

public class AddItemViewModel
{
    [Required(ErrorMessage = "Please enter an item name")]
    [Display(Name="Item Name")]
    public string Name { get; set; }

    [Display(Name="Appointments")]
    public List<Appointment> Appointments { get; set; }

    ...
    // Other properties in here
    ...
}

我正在使用Razor视图引擎。

我使用@Html.EditorFor(x => x.Property)助手可以正常运行;对于所有(但只有一个 - 暂时告诉你)根对象(Item)属性的元素。

我可以将ViewModel发布到控制器并保存一个新的Item和所有爵士乐 - 所以一切都很好。

问题
我在ViewModel中声明了List<Appointment>

如何允许用户从页面中向此Appointment添加新的List<Appointment>

我希望在发布ViewModel时将这些内容分配给要创建的Item对象 - 我将在我的控制器/服务等中执行此操作。

我怎样才能做到这一点?

所需视图
我需要用户能够在页面中添加Appointment - 无论他们喜欢多少,真的。

我希望页面上某个区域的列表(Appointment或类似内容等)中的“已创建”ul列表。

在该列表下方,我想要一些与Day的{​​{1}},FromTo属性相关的文本框 - 带有“添加”按钮,它将它附加到列表(并理想地清除文本框)

作为奖励,我还想在每个项目旁边添加某种“×” - “删除”按钮,以将其从Appointment和视图中删除。

这是一个样本(用MSPaint绘制 - 老派工具ftw!)我想象的视图:

My desired view design

我尝试过的事情
我一直在挖掘,但到目前为止还没有任何事情可以解决。

  • 我已经看过许多解决方案,可以添加对象 JavaScript到页面 - 这确实有效。唯一的问题是我做不到 在发布到控制器的对象中拾取它们。

  • 我也直接指出使用Ajax创建一个List<Appointment>对象并将其插入到页面中,但这似乎也没有被提起。

非常感谢您的专业知识,知识和智慧。

1 个答案:

答案 0 :(得分:1)

  1. 为了能够动态地在UI上添加新的约会输入控件,点击“添加”按钮,您可以
  2. [下面的代码来自我的头脑,更像是伪代码]

    a)使用jQuery / js克隆你在视图上预呈现的隐藏div,其中包含所有相关的约会控件。

    e.g。这将是一个预渲染的div,它将作为模板

    <div style="display:none;" id="appointment-template">
        <input type=text>
    </div>
    

    然后单击Add的jQuery克隆函数就像

    var addNewAppointmentRowFromTemplate = function(){
            $("#appointments-list-container").append($("#appointment-template").clone());
        }
    

    OR

    b)从服务器获取局部视图并将其附加到表单(再次使用jQuery $ .get / js xhr)

     $.get( "controller/templatDivActionMethodUrl", function( data ) {
          $("#appointments-list-container").append( data );
        });
    
    1. 为了能够使用在ActionMethod的Item参数中接受的Item中的List发送模型,您可以
    2. a)使用与服务器端模型具有相同结构的jquery / javascript动态创建json对象(模型更改时可维护性将成为问题)。

          var appointmentsJson = [];
          //foreach loop is a pseudo code, can be replaced with $.each()
          foreach (var appointment in $("#appointments-list-container").children()){
                  appointmentsJson.push(new {'day' : $(appointment).children("#day").val(),'from' : $(appointment).children("#from").val(),'to' : $(appointment).children("#to").val()})  ;}
      
          //and then post this json to actionMethod
      
          $.post("serverController/Actionmethod",{appointments: appointmentsJson});
      

      OR

      b)使用ASP.Net MVC附带的ModelBinder功能。我们在那里有大量的文档/教程,一个起点:     https://docs.asp.net/en/latest/mvc/models/model-binding.html