独特的脚本标签不起作用

Unique script tags not working

我正在主视图上创建部分视图列表。部分视图使用级联下拉列表。级联下拉菜单在第一行上运行良好,但是当我添加第二行并更改第一个下拉菜单中的值时,第二个下拉菜单也会发生变化,而不是我刚刚更新的行中的那个。 我研究并知道这是因为我的脚本对它们都使用了相同的标签而不是唯一的。 我开始使用 Html.BeginCollectionItem() 在我的下拉列表中获取唯一名称并修改我的脚本以获取隐藏字段的值并绑定到正确的下拉列表,但它不起作用。

知道如何在我的脚本中拥有唯一 ID 吗?

这是我的部分观点:

@model BudgetPortalMVC4.Models.NewBudgetModel
@using (Html.BeginCollectionItem(""))
{
    <script type="text/jscript">
        $(function () {
            var value = document.getElementsByName(".index")[0].value;
            $(document).on('change', "#["+value+"].SelectedCategory", function () {
                $("#["+value+"].SelectedSubCategory").empty();
                $.getJSON('@Url.Action("GetSubCategories")', { id: $(this).val() }, function (data) {
                    if (!data) {
                        return;
                    }
                    $("#["+value+"].SelectedSubCategory").append($('<option></option>').val('0').text('Select Item'));
                    $.each(data, function (index, item) {
                        $("#["+value+"].SelectedSubCategory").append($('<option></option>').val(item.Value).text(item.Text));
                    })
                });
            });
        });
    </script>
    <table>
       <tr>
            <td>
                <div>
                    @Html.LabelFor(m => m.SelectedCategory)
                    @Html.DropDownListFor(m => m.SelectedCategory, Model.CategoriesList, "Please select", new { @class = "SelectedCategory" })
                    @Html.ValidationMessageFor(m => m.SelectedCategory)
                </div>
            </td>
            <td>
                <div>
                    @Html.LabelFor(m => m.SelectedSubCategory)
                    @Html.DropDownListFor(m => m.SelectedSubCategory,    Model.SubCategoriesList, "Please select", new { @class = "SelectedSubCategory" })
                    @Html.ValidationMessageFor(m => m.SelectedSubCategory)
                </div>
            </td>
        </tr>
    </table>
}

这是渲染时生成的代码的一部分:

<input type="hidden" name=".index" autocomplete="off" value="b6fadec7-eb7d-4ce2-a06c-79ef0597b8da" />

<table>
    <tr>
        <td>
            <div>
                <label for="">SelectedCategory</label>
                <select class="SelectedCategory" data-val="true" data-val-number="The field SelectedCategory must be a number." name=[b6fadec7-eb7d-4ce2-a06c-79ef0597b8da].SelectedCategory"><option value="">Please select</option>
                    <option value="1">Groceries</option>
                    <option value="2">Travel</option>
                </select>
                <span class="field-validation-valid" data-valmsg-for="[b6fadec7-eb7d-4ce2-a06c-79ef0597b8da].SelectedCategory" data-valmsg replace="true"></span>

这是我的脚本在尝试使标签唯一时抛出的错误:

Error: Syntax error, unrecognized expression: #[4eebf546-988d-44a0-aa4e-296c46273d54].SelectedCategory throw new Error( "Syntax error, unrecognized expression: " + msg );

脚本永远不应该是局部的。将脚本移动到主视图(或布局)并在 jQuery 选择器中使用您的元素 class 名称。

你部分应该是

@using (Html.BeginCollectionItem(""))
{
    <div class="item">
        <label>
            <span>@Html.DisplayNameFor(m => m.SelectedCategory)</span>
            @Html.DropDownListFor(m => m.SelectedCategory, Model.CategoriesList, "Please select", new { @class = "SelectedCategory" })
            @Html.ValidationMessageFor(m => m.SelectedCategory)
        </label>
        <label>
            <span>@Html.DisplayNameFor(m => m.SelectedSubCategory)</span>
            @Html.DropDownListFor(m => m.SelectedSubCategory, Model.SubCategoriesList, "Please select", new { @class = "SelectedSubCategory" })
             @Html.ValidationMessageFor(m => m.SelectedSubCategory)
        </label>
    </div>
}

请注意,因为您的模型是 IEnumerable<T>HtmlHelper 方法不会生成 id 属性或您的表单控件,所以如果您需要标签,它们需要将控制。

另请注意,即使创建了 id 属性(假设您的模型是一个包含 属性 集合的对象),HtmlHelper 方法也会替换任何 []. 字符以及下划线以防止与 jQuery 选择器发生冲突,因此视图中永远不会存在 #[4eebf546-988d-44a0-aa4e-296c46273d54].SelectedCategory 之类的内容。

然后把脚本改成

var url = '@Url.Action("GetSubCategories", "Budget")'; // Do not hard code your url's
$(document).on('change', '.SelectedCategory', function() {
    var subCategory = $(this).closest('.item').find('.SelectedSubCategory');
    subCategory.empty();
    $.getJSON(url, { id: $(this).val() }, function (data) {
        if (!data) {
            return;
        }
        subCategory.append($('<option></option>').val('').text('Please select')); // Do not give the option a value!
        $.each(data, function (index, item) {
            subCategory.append($('<option></option>').val(item.Value).text(item.Text));
        });
    });
});

请注意,您还将 $(document) 替换为首次呈现页面时文档中存在的最接近的祖先(例如,可能是 $('form')