我正在主视图上创建部分视图列表。部分视图使用级联下拉列表。级联下拉列表在第一行上运行良好,但是当我添加第二行并更改第一个下拉列表中的值时,2秒的值也会更改,而不是我正在更新的行中的一行。
我研究并知道这是因为我的脚本为它们使用相同的标签并且不是唯一的。
我开始使用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 抛出新错误(&#34;语法错误,无法识别的表达式:&#34; + msg);
答案 0 :(得分:0)
脚本永远不应该是部分的。将脚本移动到主视图(或布局),并在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<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')
)