【问题标题】:Unique script tags not working唯一的脚本标签不起作用
【发布时间】:2016-03-18 05:17:11
【问题描述】:

我正在我的主视图上创建一个局部视图列表。局部视图使用级联下拉列表。级联下拉菜单在第一行上运行良好,但是当我添加第二行并更改第一个下拉菜单上的值时,第二个下拉菜单也会发生变化,而不是我刚刚更新的行中的一个。 我研究并知道这是因为我的脚本对它们都使用相同的标签并且不是唯一的。 我开始使用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>

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

错误:语法错误,无法识别的表达式:#[4eebf546-988d-44a0-aa4e-296c46273d54].SelectedCategory throw new Error("语法错误,无法识别的表达式:" + msg);

【问题讨论】:

  • 首先,从部分中删除你的脚本并将其放在主视图中(脚本永远不应该在部分中)。然后给你元素类名,以便你按类名而不是 ID 选择。
  • 如果您查看生成的 html,您会看到没有带有 id="[####].SelectedCategory" 的元素 - 它们将是 id="_####__SelectedCategory"(除非您的情况没有 id 属性在表单控件上,因为您的模型是一个集合而不是一个对象包含一个作为集合的属性)

标签: asp.net-mvc-4 jscript asp.net-mvc-partialview cascadingdropdown


【解决方案1】:

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

你应该是偏心的

@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&lt;T&gt;,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'))

【讨论】:

  • 感谢您的回复。我对代码进行了更改,我得到了这个响应 [{"Value":1,"Text":"Vegetables"},{"Value":2,"Text":"Ice Cream"},{"值”:3,“文本”:“肉”}]。但是它没有在第二个下拉列表中更新。有什么想法吗?
  • 那你没有听我的回答。调试您的脚本并检查值 - 例如 console.log(subCategory.length); 返回什么?我还注意到您的代码在subCategory.append($('&lt;option&lt;/option&gt;').val(... 中缺少&gt; 并且我已经更新了答案(我认为这是您的错字,但如果不是,那将导致脚本失败)
  • 这是我得到的:ReferenceError: subCategory is not defined。我试图将 $(document) 更改为 $('form') 但它没有用。也许我只需要一些文档。
  • 您是否将&lt;div class="item"&gt; 元素添加到局部视图中?如果你不使用我给你的代码,那么你不能指望它工作:)
  • 另外请注意,您不会为新项目获得任何客户端验证。建议您再次阅读我在上一个问题中给您的链接 - 您需要重新解析验证器。
猜你喜欢
  • 2017-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多