我有一个用于创建视图的viewmodel类,它包含2个不同类的属性,以及一个选择项列表(用于下拉列表)。下拉列表和其中一个类的字段始终显示在视图中,但仅当选择了列表的特定选项时,才会显示第二个类的字段。 (通过jQuery加载和返回局部视图的控制器,为第二类强类型化)
第二个类视图中的字段是一些正常输入=文本字段和一个下拉列表。
当我提交表单时,除了第二类内的列表值之外,所有数据都将被正确绑定。
问题是,如果存在验证错误,并且我返回带有模型的视图(以显示错误),那么下拉列表(第二类的那个)是空的,因为没有办法选择从中,然后提交将始终具有isValid = false:S
这是我如何设置的一个例子:
我目前的视图模型如下所示:
public class ViewModel
{
public GenericData genericData{get;set;}
public SpecializedData specializedData {get;set;}
public List<SelectListItem> types { get; set; }
}
public class GenericData
{
public Type type {get;set;}
public String name {get;set;}
public String description{get;set;}
}
public class SpecializedData
{
public String field{get;set;}
public int foreignKey{get;set;}
public List<SelectListItem> listOfForeignKeys{ get; set; }
}
视图是ViewModel的强类型,并以这种方式设置:
<p>
<label for="genericData.type"> Type: </label>
<%=Html.DropDownList("genericData.type",Model.types, "Choose a type") %>
</p>
<p>
<label for="genericData.name"> Name:</label>
<%: Html.TextBox("genericData.name")%>
<%= Html.ValidationMessage("genericData.name", "*")%>
</p>
//Same thing for Description as for name
<div id="SpecializedFields">
//This will display the specialized info it was already captured before.
<% if (Model.SpecializedData!= null && Model.GenericData.Type == "Specialized")
{
Html.RenderPartial("SpecializedInfoView", Model.specializedData);
} %>
</div>
<p>
<input type="submit" value="Create" />
</p>
$(document).ready(function () {
$("#CatalogItem_Type").change(function () {
var typeVal = $("#GenericData_type").val();
if (typeVal == "specialized") {
$("#SpecializedFields").load("/MyController/SpecializedFields");
}
控制器会做这样的事情
public ActionResult SpecializedFields()
{
List<SelectListItem> foreignIds = getForeignIdsFromDataBase();
SpecializedData model = new SpecializedData ();
model.listOfForeignIds = foreignIds;
return PartialView("SpecializedInfoView",model);
}
最后,SpecialezedInfoView是SpecializedData的强类型视图,类似于泛型视图,它是这样的:
<p>
<label for="specializedData.foreignKey"> Key: </label> <%=Html.DropDownList("specializedData.foreignKey",Model.listOfForeignKeys, "Choose key") %>
</p>
<p>
<label for="SpecializedData.field"> Field:</label>
<%: Html.TextBox("specializedData.field")%>
<%= Html.ValidationMessage("specializedData.field", "*")%>
</p>
当我点击提交时,如果它不是专门的项目,我将获得specializedData
属性的空值,这没关系。如果它是一个专门的项目,那么它不会为空,我将获得genericData
的所有属性,我也会获得specializedData.field
和specializedData.foreignKey
值,但是specialized.listOfForeignKeys
将是NULL
,这意味着如果存在验证错误并且我使用当前模型返回视图,则所有内容都将具有先前输入的值,但 DropDownList与列表外键的内容为空,现在无法选择ID。
我知道我可以在接收帖子的方法中查看expertData是否为null,并重新生成密钥列表并将其分配给当前模型(因为它是唯一缺少的数据) ,但这意味着必须进行额外的数据库调用,而不是模型中存在的信息!
我知道这是一个很长的问题,但我想明确我是如何设置的,有人知道为什么listOfForeignKeys在回发后没有被传回模型!?
谢谢!
答案 0 :(得分:4)
我想通了......当你绑定时,DropDownLists
的值不会被发送回模型...但是,由于绑定会自动调用viewmodel的构造函数{{ 1}}因为绑定而被填充在那里。第二个列表不是在构造函数中构建的,因此它是null。我添加了查询以获取List<SelectItemList> Types
构造函数中列表的信息,现在它正在工作..
当用户点击发布时,会有一个额外的数据库调用,而且如果存在验证错误则会更多次调用。也许我会尝试使用缓存来存储查询结果,但就目前而言,这已经足够了。
谢谢!