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

Geo*_*mes 5 javascript c# asp.net-mvc viewmodel

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

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

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

Item具有一定的特性,这都得到一个新行加入DB很好.

Item还包含一个List<Appointment>声明它的s(我将序列化这些并将它们保存在适当的列中).

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

我已经设置了一个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
    ...
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Razor视图引擎.

我使用@Html.EditorFor(x => x.Property)帮手一切正常; 对于所有(但只有一个 - 稍后告诉你)根对象的(Items)属性的元素.

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

问题
List<Appointment>在我的ViewModel中声明了一个.

我怎样才能让用户新添加Appointments到这种List<Appointment>页?

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

我怎样才能做到这一点?

期望的视图
我需要用户能够Appointment在页面中添加s - 实际上是他们喜欢的多少.

我希望在页面上的某个区域中Appointment列出一个"已创建" 的列表(ul或任何类似的等).

下面这个列表,我想一些文本框是相关的Day,FromTo属性的Appointment-用"添加"按钮,它追加到列表中(并清除文本框,理想情况下).

作为奖励,我还想在每个项目旁边添加某种"×" - "删除"按钮,以便从List<Appointment>视图中删除它.

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

我想要的视图设计

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

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

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

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

Sah*_*rsh 1

  1. 为了能够在 UI 上动态添加新的约会输入控件,单击“添加”按钮后,您可以

[下面的代码来自我的头脑,更像是伪代码]

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

例如,这将是一个预渲染的 div,它将用作模板

<div style="display:none;" id="appointment-template">
    <input type=text>
</div>
Run Code Online (Sandbox Code Playgroud)

然后单击“添加”时的 jQuery 克隆功能将类似于

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

或者

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

 $.get( "controller/templatDivActionMethodUrl", function( data ) {
      $("#appointments-list-container").append( data );
    });
Run Code Online (Sandbox Code Playgroud)
  1. 为了能够发送在 ActionMethod 的 Item 参数中接受的 Item 中包含 List 的模型,您可以

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});
Run Code Online (Sandbox Code Playgroud)

或者

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