将多个项添加到列表而不回发

时间:2015-02-12 09:45:38

标签: asp.net-mvc entity-framework

我的模型有一个list属性,在视图中我需要能够为它添加无限数量的字符串。 到目前为止,它没有工作,我的糟糕想法使其工作如下:每次添加一个字符串,都有一个回发。新字符串位于ViewModel的“newString”属性中(不是列表)。然后,HttpPost方法将“newString”保存到数据库,使用存储在数据库中的所有字符串重新填充列表“allStrings”,并返回包含所有字符串和emtpy文本框的视图以添加另一个字符串。

这对我来说不是一个好的解决方案,因为:

  • 如果用户想要添加多个字符串,那么会有很多回发
  • 如果用户在其商品(供应商)中添加了一些字符串,则所有这些字符串都会保存到数据库中。当他决定不想保存供应商时,所有存储的字符串都是无用的,需要从数据库中删除。

我没有实现这个,因为我知道有更好的解决方案,我只是找不到它们。这就是我所拥有的:

ViewModel:

public class SupplierViewModel
{
    public Supplier Supplier { get; set; }
    public List<string> allStrings;
    public string newString { get; set; }
}

控制器:

    [HttpPost]
    public ActionResult Create(SupplierViewModel model)
    {
        model.allStrings.Add(model.newString);

        if (ModelState.IsValid && model.newString == "")  
            db.Suppliers.Add(model.Supplier);
            db.SaveChanges();

            return RedirectToAction("Index");
        }

        model.newString = "";
        return View(model);
    }

观点:

   <div class="editor-label">
        @Html.LabelFor(model => model.allStrings)
    </div>

    @for (int i = 0; i < Model.allStrings.Count; i++)
    {
        <div class="editor-label">
            @Html.EditorFor(model => model.allStrings[i])
        </div>
    }

    <div class="editor-label">
        @Html.EditorFor(model => model.newString)
    </div>

请注意,在此实现的版本中,没有任何字符串保存到数据库,并且每次回发后都会清除列表。在视图上只显示一个字符串(添加的最后一个字符串)。

基本上问题是:如何让用户尽可能多地使用回发和数据库交互添加尽可能多的字符串?

提前致谢

1 个答案:

答案 0 :(得分:3)

您可以使用jquery动态添加新元素,这些元素将发布回您的收藏集。您为文本框生成的html将类似于

<input type="text" name="allStrings[0]" .../>
<input type="text" name="allStrings[1]" .../>

name属性包含一个允许DefaultModelBinder绑定集合的索引器。

将文本框包装在容器中,包括添加新项目的按钮,获取副本并添加到DOM的输入。

<div id="strings">
  @for (int i = 0; i < Model.allStrings.Count; i++)
  {
    <div class="editor-label">
        @Html.TextBoxFor(m => m.allStrings[i])
    </div>
  }
</div>
<div id="newstring" style="display:none;">
  <input type="text" name="allStrings[#]" />
</div>
<button type="button" id="addstring">Add</button>

脚本

var container = $('#strings');
$('#addstring').click(function() {
  var index = container.children('input').length;
  var clone = $('#newstring').clone();
  clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
  container .append(clone.html());
});

请参阅this fiddle了解工作示例

请注意,您的模型不再需要public string newString { get; set; }属性,当您回发时,您的收藏集将包含文本框的所有值。