ASP.NET DropDownList绑定JavaScript onchange事件遇Model未定义错误
解决“uncaught referenceerror: Model is not defined”错误并实现产品数据预填充
错误原因
Model是Razor Pages的服务器端对象,页面渲染完成后浏览器端的JavaScript无法直接访问这个对象,所以在前端脚本中直接调用Model.Product会触发未定义的错误。
解决方案
需要把服务器端的产品数据序列化为JSON格式,注入到前端页面中,让JavaScript可以访问到这些数据,同时修正脚本中的变量引用错误。
步骤1:在页面中注入产品JSON数据
在Razor视图中,使用Json.Serialize把Model.Product序列化为JSON字符串,存储到前端的全局变量中:
<!-- 在脚本前添加,确保先加载数据 --> <script> // 将服务器端产品数据序列化为前端可访问的JSON对象 const products = @Json.Serialize(Model.Product); </script>
步骤2:修正JavaScript脚本
修改changeDropDownValue函数,使用上面定义的products变量,同时修正变量混淆的问题(之前错误地用selectedProductId访问产品属性,应该用selectedProduct):
<script> function changeDropDownValue(test) { const selectedProductId = parseInt(document.getElementById("productOptions").value); // 从前端的products数组中查找选中的产品 const selectedProduct = products.find(product => product.ID === selectedProductId); if (selectedProduct) { // 更新输入字段值 document.getElementById("test").value = selectedProduct.Description; document.querySelector('input[name="Product[0].Quantity"]').value = selectedProduct.Quantity; document.querySelector('input[name="Product[0].UnitPrice"]').value = selectedProduct.UnitPrice; document.querySelector('input[name="Product[0].Discount"]').value = selectedProduct.Discount; document.querySelector('input[name="Product[0].Vat"]').value = selectedProduct.Vat; document.querySelector('input[name="Product[0].NetTotal"]').value = selectedProduct.NetTotal; } } </script>
说明:Razor Pages中
asp-for="Product[0].Quantity"生成的id是Product_0__Quantity(用下划线替代方括号和点),用name属性查找元素更可靠,避免依赖生成的id。
修改后的完整视图代码片段
<tbody> <tr> <td> <select class="btn btn-success" id="productOptions" onchange="changeDropDownValue(this)"> @foreach (var product in Model.Product) { <option value="@product.ID">@product.Name</option> } </select> </td> <td> <input asp-for="Product[0].Description" id="test" disabled /> <span asp-validation-for="Product[0].Description" class="text-danger"></span> </td> <td> <input asp-for="Product[0].Quantity" /> <span asp-validation-for="Product[0].Quantity" class="text-danger"></span> </td> <td> <input asp-for="Product[0].UnitPrice" disabled /> <span asp-validation-for="Product[0].UnitPrice" class="text-danger"></span> </td> <td> <input asp-for="Product[0].Discount" /> <span asp-validation-for="Product[0].Discount" class="text-danger"></span> </td> <td> <input asp-for="Product[0].Vat" disabled /> <span asp-validation-for="Product[0].Vat" class="text-danger"></span> </td> <td> <input asp-for="Product[0].NetTotal" disabled /> <span asp-validation-for="Product[0].NetTotal" class="text-danger"></span> </td> </tr> </tbody> <!-- 注入产品数据 --> <script> const products = @Json.Serialize(Model.Product); </script> <script> function changeDropDownValue(test) { const selectedProductId = parseInt(document.getElementById("productOptions").value); const selectedProduct = products.find(product => product.ID === selectedProductId); if (selectedProduct) { document.getElementById("test").value = selectedProduct.Description; document.querySelector('input[name="Product[0].Quantity"]').value = selectedProduct.Quantity; document.querySelector('input[name="Product[0].UnitPrice"]').value = selectedProduct.UnitPrice; document.querySelector('input[name="Product[0].Discount"]').value = selectedProduct.Discount; document.querySelector('input[name="Product[0].Vat"]').value = selectedProduct.Vat; document.querySelector('input[name="Product[0].NetTotal"]').value = selectedProduct.NetTotal; } } </script>
额外说明
- 确保
Product模型的属性(ID、Name、Description等)是可序列化的,避免包含无法序列化为JSON的类型(比如复杂对象、循环引用)。 - 添加
if (selectedProduct)判断,防止用户选择默认的“Select New Product”选项时出现错误。
内容的提问来源于stack exchange,提问作者abtrini
相关产品推荐
相关产品推荐

