2017-10-20 46 views
0

我正在MVC应用程序内部的asp.net核心中工作。我正在使用基于模型创建视图和控制器的脚手架功能。以下是我正在使用的模型:创建在运行时增长的动态表单

class ShoppingList 
{ 
    public int ShoppingListId { get; set; } 
    public string Name { get; set; } 
    public List<string> ListItems { get; set; }    
} 

通过视图向用户显示的窗体仅显示名称的字段。我希望表单能够显示列表项目的字段,然后如果用户想要添加另一个列表项目,他们可以点击按钮添加另一个字段来执行此操作。他们在运行时决定他们想要添加多少购物清单项目。

这里是剃刀CSHTML形式我使用:

<form asp-action="Create"> 
    <div asp-validation-summary="ModelOnly" class="text-danger"></div> 
     <div class="form-group"> 
      <label asp-for="Name" class="control-label"></label> 
      <input asp-for="Name" class="form-control" /> 
      <span asp-validation-for="Name" class="text-danger"></span> 
     </div> 
    <div class="form-group"> 
    <input type="submit" value="Create" class="btn btn-default" /> 
    </div> 
</form> 

是否有一个简单的方法来做到这一点?我不想硬编码一个数字。

+0

使用jQuery将输入元素添加到DOM。 – Shyju

+0

我得到的问题是,当我提交表单时,新添加的元素不会与提交一起发送。 @Shyju – conterio

+0

它只要我们的名字与模型绑定器正在寻找的内容相匹配就可以实现。分享你试过的代码 – Shyju

回答

1

如果你想允许用户在你需要使用JavaScript来更新客户端添加一个新的表单元素DOM与你想添加的新元素。要列出现有的项目,您可以使用编辑器模板。混合这两个将给你一个动态的形式。以下是一个基本的实现。

要使用编辑器模板,我们需要为属性类型创建一个编辑器模板。我不会那样做string类型,它更像是一个通用的类型。我会创建一个自定义类来表示列表项。

public class Item 
{ 
    public string Name { set; get; } 
} 
public class ShoppingList 
{ 
    public int ShoppingListId { get; set; } 
    public string Name { get; set; } 
    public List<Item> ListItems { get; set; } 

    public ShoppingList() 
    { 
     this.ListItems=new List<Item>(); 
    } 
} 

现在,~/Views/YourControllerName~/Views/Shared/下创建一个名为EditorTemplates目录,并创建一个名为Item.cshtml视图里面会有下面的代码

@model YourNameSpaceHere.Item 
<input type="text" asp-for="Name" class="items" /> 

现在,在您的GET控制器,创建ShoppingList的对象,发送到视图。

public IActionResult ShoppingList() 
{ 
    var vm = new ShoppingList() { }; 
    return View(vm); 
} 

现在在主视图,所有你需要做的就是调用EditorFor方法

@model YourNamespace.ShoppingList 
<form asp-action="ShoppingList" method="post"> 
    <input asp-for="Name" class="form-control" /> 
    <div class="form-group" id="item-list"> 
     <a href="#" id="add">Add</a> 
     @Html.EditorFor(f => f.ListItems) 
    </div> 
    <input type="submit" value="Create" class="btn btn-default" /> 
</form> 

的标记有新增项目的一个锚标记。因此,当用户点击它,我们需要与name属性值的格式添加一个新的输入元素ListItems[indexValue].Name

$(function() { 

    $("#add").click(function (e) { 
     e.preventDefault(); 
     var i = $(".items").length; 
     var n = '<input type="text" class="items" name="ListItems[' + i + '].Name" />'; 
     $("#item-list").append(n); 
    }); 

}); 

因此,当用户点击它增加了使用正确的名称到DOM,当一个新的输入元素您单击提交按钮模型绑定将正常工作,因为我们具有输入的正确名称属性值。

[HttpPost] 
public IActionResult ShoppingList(ShoppingList model) 
{ 
    //check model.ListItems 
    // to do : return something 
} 

如果你想预加载一些现有的项目(编辑画面等),所有你需要做的就是加载listItems属性和编辑模板将渲染输入元素与正确名称每个项目的护理属性值。

public IActionResult ShoppingList() 
{ 
    var vm = new ShoppingList(); 
    vm.ListItems = new List<Item>() { new Item { Name = "apple" } } 
    return View(vm); 
} 
0

首先这是你必须有一个公共存取你的ShoppingList类。因此,public class ShoppingList

接下来是您的看法将需要以下更改。

@model ShoppingList 

<h1>@Model.Name</h1> 
<h2>@Model.ShoppingListId</h2> 
foreach(var item in Model.ListItems) 
{ 
    <h3>@item</h3> 
} 

所以,上面的代码大致是你在找什么。 在Razor中,您可以通过在视图顶部使用@model来访问模型变量。但有一点你需要注意的是,如果你的模型是在一个子文件夹中,你需要在其中进行说明。

下面是一个例子:@model BethanysPieShop.Models.ShoppingCart

这里BethanysPieShop是我的项目名称,型号是我的文件夹中的ShoppingCart类是英寸