8

我是 ASP.NET MVC 的新手,如果这比看起来容易,我深表歉意。我一直在谷歌搜索,我有这样的课程

public class Search : IAuditable
{
    [Key]
    public int SearchID { get; set; }
    public int UserID { get; set; }

    ...

    public ICollection<SearchTerm> SearchTerms { get; set; }   
}

Create.cshtml中,我有以下内容

<div class="editor-label">
    @Html.LabelFor(model => model.Search.SearchTerms)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Search.SearchTerms, "SearchTerm")
    @Html.ValidationMessageFor(model => model.Search.SearchTerms)
</div>

SearchTerm EditorTemplate是一个简单的形式,如下所示:

@model Core.Search.Parameters.SearchTerm

@Html.HiddenFor(n => n.SearchTermID)
<div class="editor-label">
    @Html.LabelFor(n => n.Text, "Term")
</div>
<div class="editor-field">
    @Html.EditorFor(n => n.Text)
    @Html.ValidationMessageFor(n => n.Text)
</div>

它似乎有效,我在创建时看到一个文本框(当默认模型为空时)。但是,我想要做的是能够SearchTerms使用Add 按钮添加/删除,以便用户可以在 create 上向集合中添加任意数量的术语。这是以某种方式内置的吗?是否有一个与之匹配的javascript框架,它将生成适当的html名称,所以我不必手动执行此操作?考虑到我是 MVC 的新手,我是否以正确的方式接近这一点?

谢谢!

4

3 回答 3

6

在这种情况下,我更喜欢使用 PartialView。

您应该创建一个 ActionResult,它会为您的项目返回 PartialView。当您单击“添加”按钮时,您应该向此 ActionResult 发送 ajax 请求。

public ActionResult GetTermItem()
{
    return PartialView("_SearchTerm", new SearchTerm());
}

您的 PartialView 应如下所示:

@model Core.Search.Parameters.SearchTerm
@{ ViewContext.FormContext = new FormContext(); }
@using (Html.BeginCollectionItem("SearchTerms"))
{
    <div class="search-term-item">            
       @Html.HiddenFor(n => n.SearchTermID)
       <div class="editor-label">
          @Html.LabelFor(n => n.Text, "Term")
       </div>
       <div class="editor-field">
          @Html.EditorFor(n => n.Text)
          @Html.ValidationMessageFor(n => n.Text)
       </div>

       <a href="javascript:void(0);" class="remove-search-item" title="Remove">Remove</a>
    </div>
}

您的主页:

<div class="editor-label">
    @Html.LabelFor(model => model.Search.SearchTerms)
</div>
<div id="search-terms-container" class="editor-field">
    @if (Model.SearchTerms != null && Model.SearchTerms.Any())
    {
        foreach (var item in Model.SearchTerms)
        {
             @Html.Partial("_SearchTerm", item)
        }
    }
</div>
<a href="javascript:void(0);" id="add-search-item">Add</a>

还有你的 JavaScript (jQuery) 部分:

$(document).on('click', '#add-search-term', function () {
    $.ajax({
        url: '@Url.Action("GetTermItem")',
        cache: false,
        success: function (data) {
            var cl = $('#search-terms-container');
            cl.append(data);
            var terms = cl.find('.search-term-item');
            terms.last().hide().show('blind');
        }
    });
    return false;
});

$(document).on('click', '.remove-search-term', function () {
    $(this).closest('.search-term-item').hide('blind', function () { $(this).remove(); });
    var cl = $('#search-terms-container');
    var terms= cl.find('.search-term-item');
    return false;
});
于 2014-02-17T11:45:01.833 回答
0

我在用户表单中对地址做了类似的事情,添加尽可能多的地址,就像你点击 + 按钮一样,这是代码

看法

$(document).on("click", "#addRowInd", function (ev) {
    ev.preventDefault();
    var index = (($("input[name^='Indirizzi']").filter(":hidden").length));
    var input = "<table>";
    input += "<tr>";
    input += "<td><label for=\"Indirizzi_"+index+"__Descrizione\">Descrizione</label></td>";
    input += "<td><input id=\"Indirizzi_" + index + "__Descrizione\" type=\"text\" name=\"Indirizzi[" + index + "].Descrizione\"></td>";
    input += "</tr>";
    input += "<tr>";
    input += "<td><label for=\"Indirizzi_" + index + "__Citta\">Citta</label></td>";
    input += "<td><input id=\"Indirizzi_" + index + "__Citta\" type=\"text\" name=\"Indirizzi[" + index + "].Citta\"></td>";
    input += "</tr>";
    input += "<tr>";
    input += "<td><label for=\"Indirizzi_" + index + "__Provincia\">Provincia</label></td>";
    input += "<td><input id=\"Indirizzi_" + index + "__Provincia\" type=\"text\" name=\"Indirizzi[" + index + "].Provincia\"></td>";
    input += "</tr>";
    input += "<tr>";
    input += "<td><label for=\"Indirizzi_" + index + "__Cap\">Cap</label></td>";
    input += "<td><input id=\"Indirizzi_" + index + "__Cap\" type=\"text\" name=\"Indirizzi[" + index + "].Cap\"></td>";
    input += "</tr>";
    input += "<tr>";
    input += "<td><label for=\"Indirizzi_" + index + "__Via\">Via</label></td>";
    input += "<td><input id=\"Indirizzi_" + index + "__Via\" type=\"text\" name=\"Indirizzi[" + index + "].Via\"></td>";
    input += "</tr>";
    input += "</table>";
    $('#tabella').find('tr.indirizzo:last').after("<tr class=\"indirizzo\"><td>Indirizzo <img src=\"/Content/layout/ico-cancella-8.png\" class=\"cancInd\" id=\"" + index + "\" /></td><td>" + input + "</td></tr>");
});

[...]

<tr class="indirizzo">
    <td>@Html.LabelFor(m => Model.Indirizzi) <input id="addRowInd" type="button" /></td>
    <td>@Html.EditorFor(m => m.Indirizzi[0])</td>
</tr> 

模型

public class ContattoModel
{
    [...]
    [Display(Name = "Indirizzo")]
    public List<Indirizzi> Indirizzi { get; set; }
    [...]
}

和控制器

public ActionResult ContattiForm([ModelBinder(typeof(ContattiBinder))]ContattoModel model){

 [...]
}

所以在我的model.Indirizzi中,我得到了我通过+按钮添加的所有地址

于 2014-02-13T16:03:25.003 回答
0

如果你想真正地绑定模型,你需要使用 Ajax 或 JQuery/javavscript。添加时,您可以执行:

$(".editor-field").load(url, function(){ // anonymous return call });

或者,仅通过 javascript 添加搜索词可能更简单。只要元素的名称匹配,MVC 就会将数据作为 IEnumerable 发送到服务器。因此,如果您的模型包含 SearchTerms,EditorFor 将为每个项目名称附加一个索引,即 SearchTerms[0].Name。这样,所有映射基本上都在幕后发生,但是,可以克隆您的术语并修改

$("#YourClone").attr("name", "SearchTerms" + index);
于 2014-02-13T15:07:05.080 回答