0

我有一个带有表格的页面,该表格带有一个按钮来动态添加行以及一种删除行的方法。每行有 2 个级联的下拉列表。创建行时,我使用 AJAX 调用来填充第一个下拉列表中的值。在此下拉列表的更改事件中,我执行另一个 AJAX 调用来填充第二个下拉列表。这一切都很好,但我的问题是,当我用最初应该显示的数据加载屏幕时,我可以用 AJAX 调用填充下拉列表,但我猜该值没有被选中,因为它是在绑定到我的之后被填充的模型。有没有办法正常处理这种情况?下面是我的文档准备功能中的代码

$(document).ready(function () {
    $.getJSON('@Url.Action("GetAll", "Customers")', function (customers) {
        var customerSelect = $('.Customers');
        customerSelect.empty();
        customerSelect.append('<option value="0">Choose Customer...</option>');
        $.each(customers, function (index, customer) {
            customerSelect.append($('<option/>', {
                value: customer.ID,
                text: customer.CustomerName
            }));
        });
    });
});

如果此信息有帮助,这里是加载表格的 HTML 代码

<table id="Attendees" class="table-gridview">
        <thead>
            <tr>
                <th style="width:320px">
                    Customer
                </th>
                <th style="width:250px">
                    Attendee
                </th>
                <th>
                    Attended
                </th>
                <th>
                    Paid
                </th>
                <th style="width:120px">
                    Check Number
                </th>
                <th>

                </th>
            </tr>
        </thead>
        <tbody>
            @Html.EditorFor(x => x.Attendees)
        </tbody>
    </table>

以下代码是与会者编辑器模板中的内容

<tr class="ClassAttendee">

    <td>
        @Html.HiddenFor(model => model.ID)
        @Html.HiddenFor(model => model.ClassID)

        @Html.DropDownList("Customers", Enumerable.Empty<SelectListItem>(), new { @Class = "Customers", style="width:300px" })
    </td>
    <td>    
        @Html.DropDownListFor(
            x => x.CustomerEmailID,
            Enumerable.Empty<SelectListItem>(),
            "Choose Attendee...",
                              new { @Class = "Contact", style = "width:220px" }
        )
        @Html.ValidationMessageFor(model => model.CustomerEmailID)
    </td>
    <td>    
        @Html.CheckBoxFor(model => model.Attended)
        @Html.ValidationMessageFor(model => model.Attended)
    </td>
    <td>    
        @Html.CheckBoxFor(model => model.FeePaid, new { @Class = "FeePaid"})
        @Html.ValidationMessageFor(model => model.FeePaid)
    </td>
    <td>    
        @if (Model.FeePaid != true)
        {
            @Html.TextBoxFor(model => model.CheckNumber, new { @Class = "CheckNumber", disabled ="true", style = "width:100px" })
        }
        else
        {
            @Html.TextBoxFor(model => model.CheckNumber, new { @Class = "CheckNumber", style = "width:100px" })
        }

        @Html.ValidationMessageFor(model => model.CheckNumber)
    </td>
    <td>
        @Html.HiddenFor(x => x.Delete, new { @class = "mark-for-delete" })
        @Html.LinkToRemoveNestedFormUpdateCounter("Remove", "tr.ClassAttendee", "input.mark-for-delete")
    </td>
</tr>

我要展示的最后一部分是 AJAX 调用的服务器端代码

public JsonResult GetAll()
    {
        var customers = customerRepository
            .All
            .Select(p => new
            {
                p.ID ,
                p.CustomerName
            })
            .OrderBy(o => o.CustomerName);
        return Json(customers, JsonRequestBehavior.AllowGet);
    }
4

2 回答 2

0

因此,当我加载页面时,我设法通过不使用 editorfor 来实现此功能。相反,我现在用下面的代码填充表格

<table id="Attendees" class="table-gridview">
        <thead>
            <tr>
                <th style="width:320px">
                    Customer
                </th>
                <th style="width:250px">
                    Attendee
                </th>
                <th>
                    Attended
                </th>
                <th>
                    Paid
                </th>
                <th style="width:120px">
                    Check Number
                </th>
                <th>

                </th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Attendees)
            {
              <tr class="ClassAttendee">
                <td>
                    @Html.HiddenFor(model => item.ID)
                    @Html.HiddenFor(model => item.ClassID)

                    @Html.DropDownList("Customers", ((IEnumerable<TRIOSoftware.Domain.Entities.Customer>)ViewBag.PossibleCustomers).Select(option => new SelectListItem
                   {
                       Text = (option == null ? "None" : option.CustomerName),
                       Value = option.ID.ToString(),
                       Selected = (Model != null) && (option.ID == item.CustomerEmail.CustomerID)
                   }),"Choose Customer...", new { @Class = "Customers", style = "width:300px" })
                </td>
                <td> 
                     @Html.DropDownListFor(model => item.CustomerEmailID, ((IEnumerable<TRIOSoftware.Domain.Entities.CustomerEmail>)ViewBag.PossibleContacts).Where(o => o.CustomerID == item.CustomerEmail.CustomerID).Select(option => new SelectListItem
                    {
                        Text = (option == null ? "None" : option.Name),
                        Value = option.ID.ToString(),
                        Selected = (Model != null) && (option.ID == item.CustomerEmailID)
                    }), "Choose Attendee...")   
                    @*@Html.DropDownListFor(model => item.CustomerEmailID, Enumerable.Empty<SelectListItem>(), "Choose Attendee...", new { @Class = "Contact", style = "width:220px" })*@
                    @Html.ValidationMessageFor(model => item.CustomerEmailID)
                </td>
                <td>    
                    @Html.CheckBoxFor(model => item.Attended)
                    @Html.ValidationMessageFor(model => item.Attended)
                </td>
                <td>    
                    @Html.CheckBoxFor(model => item.FeePaid, new { @Class = "FeePaid" })
                    @Html.ValidationMessageFor(model => item.FeePaid)
                </td>
                <td>    
                    @if (item.FeePaid != true)
                    {
                        @Html.TextBoxFor(model => item.CheckNumber, new { @Class = "CheckNumber", disabled = "true", style = "width:100px" })
                    }
                    else
                    {
                        @Html.TextBoxFor(model => item.CheckNumber, new { @Class = "CheckNumber", style = "width:100px" })
                    }

                    @Html.ValidationMessageFor(model => item.CheckNumber)
                </td>
                <td>
                    @Html.HiddenFor(x => item.Delete, new { @class = "mark-for-delete" })
                    @Html.LinkToRemoveNestedFormUpdateCounter("Remove", "tr.ClassAttendee", "input.mark-for-delete")
                </td>
            </tr>
            }
        </tbody>
    </table>

基本上,我将模板代码移动到视图中,而不是使用 AJAX 填充下拉列表,而是使用发送到视图中的数据填充初始的。

我会把这个问题留一点,看看是否有人提出更好的答案,因为在我看来这似乎是一个蛮力解决方案。

编辑 - - - - - - - - - - - - - - - - - - - - - - - - - ------------------------------

我在将此解决方案传递回控制器以保存时遇到问题。由于我发现没有其他方法可以使其工作,我将其添加到视图的文档就绪功能中

 $("#Attendees tr").each(function (index) {
        $(this).find("input, select, span").each(function (indx, element) {
            if ($(element).attr('name') !== undefined) {
                var name = $(element).attr('name').replace("item", "Attendees[" + (index - 1) + "]");
                $(element).attr('name', name);
            } else {
                // attribute does not exist
            }

            if ($(element).attr('id') !== undefined) {
                var id = $(element).attr('id').replace("item", "Attendees_" + (index - 1) + "_");
                $(element).attr('id', id);
            } else {
                // attribute does not exist
            }

            if ($(element).attr('data-valmasg-for') !== undefined) {
                var dataval = $(element).attr('data-valmasg-for').replace("item", "Attendees[" + (index - 1) + "]");
                $(element).attr('data-valmasg-for', dataval);
            } else {
                // attribute does not exist
            }
        });


    });

基本上我会用正确的名称替换项目 ID 和名称,以将我的数据返回到控制器。这有点骇人听闻,但它确实有效,所以我想发布它。

于 2012-12-13T20:36:54.703 回答
0

我没有对此进行测试,但是您可以执行以下操作:

$(document).ready(function () {
    $.getJSON('@Url.Action("GetAll", "Customers")', function (customers) {
        var customerSelect = $('.Customers');
        customerSelect.empty();
        customerSelect.append('<option value="0">Choose Customer...</option>');
        $.each(customers, function (index, customer) {

            var option=$('<option/>', {
                value: customer.ID,
                text: customer.CustomerName
            });
            if(customer.ID=='@(Model.CustomerEmailID)')
                 $(option).attr("selected","selected");

            customerSelect.append(option);

        });
    });
});

更新

如果您可以将选定的 id 添加为父级的属性,<td>例如:

<td data-id="@(Model.CustomerEmailID)">    
    @Html.DropDownListFor(
        x => x.CustomerEmailID,
        Enumerable.Empty<SelectListItem>(),
        "Choose Attendee...",
                          new { @Class = "Contact", style = "width:220px" }
    )
    @Html.ValidationMessageFor(model => model.CustomerEmailID)
</td>

你可以这样做:

$(document).ready(function () {
    $.getJSON('@Url.Action("GetAll", "Customers")', function (customers) {
        var customerSelect = $('.Customers');
        customerSelect.empty();
        customerSelect.append('<option value="0">Choose Customer...</option>');
        $.each(customers, function (index, customer) {

            var option=$('<option/>', {
                value: customer.ID,
                text: customer.CustomerName
            });
            if(customer.ID==$(this).parent().attr("data-id"))
                 $(option).attr("selected","selected");

            customerSelect.append(option);

        });
    });
});
于 2012-12-13T20:41:30.483 回答