2016-04-28 71 views
-1

我有一个下拉列表表的每一行中,像这样的:如何使DropDownListFor使用项目ID而不是索引?

@Html.DropDownListFor(m => m.Transactions[i].CategoryID, ...) 

,一切大多工作。我可以选择项目,提交表格,模型中有我更新的选择。到现在为止还挺好。

问题是这不是很可靠。由于每个下拉菜单的名称都是基于索引而不是ID,这意味着帖子值与生活在数据库中的实际项目之间的匹配基于索引。大部分时间工作正常,但如果项目列表在页面加载时间和用户执行回发时间之间发生变化,该怎么办?指数发生了变化,这意味着发布的数据不能正确匹配,并且发生不好的事情。或者我看到浏览器不正确地尝试在帖子之间的下拉列表中保留选择,但是因为项目列表正在改变(在页面刷新的时候项目#2现在可能是项目#3)并且一切都基于在指数上,错误的下拉得到错误的值。

所以基本上,我怎么能强制下拉菜单生成看起来更像这样一个名称和ID:

Transactions_CategoryID_12385652 // 12385652 is the CategoryID 

,而不是这样的:

Transactions_4_CategoryID // 4 is the array index 

,而且还有自动的好处捆绑?

编辑:我提到的第二个问题(输入值刷新后不正确地恢复)似乎只发生在Firefox。 https://bugzilla.mozilla.org/show_bug.cgi?id=46845

+0

简短的回答是否定的。而且你甚至不会尝试更改'name'属性,因为这意味着模型绑定会失败。您需要在视图中包含模型'id'属性,以便'CategoryID'与其相关的'ID'匹配 - @@ Html.HiddenFor(m => m.Transactions [i] .ID)' –

+0

@StephenMuecke隐藏的领域将有所帮助。即使交易清单发生变化(我提到的第一种情况),它也会确保我始终更新正确的交易。但它仍然不会阻止浏览器使用下拉列表中的值(第2种情况)。 – BradDaBug

+0

对不起,我不明白你的意思是_浏览器可能会隐藏dropdowns_中的值吗? –

回答

0

您必须编写自己的自定义模型联编程序以及Html扩展名才能以此方式生成元素名称,或者您可以使用Razor手动生成标记。

您是否有特殊的理由需要这样做?除非有充分理由不这样做,否则几乎总是遵循框架的约定。

0

您可以将想要的确切集合传递给视图并将其绑定到DropDownFor html帮助器。

假设你有一个人。

public class Person 
{ 
    public int Id { get; set; } 
    public int Name { get; set; } 
} 

而你想添加一个新的人。创建一个视图模型。在SelectList类型的此视图模型中创建一个属性。这个选择列表将保存您想要填充下拉列表的模型的集合。

public class PersonViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public SelectList MySelectList { get; set; } 
} 

假设您希望下拉列表中的人员ID保持为选定值,人员姓名保存为文本值。您可能想要创建第二个视图模型来表示该模型或使用匿名对象。我们调用集合myCollection。假设该集合由具有两个属性(以及Id和Name属性)的对象组成。现在只需将该视图模型与MySelectList的值一起传递即可。

var viewModel = new MyViewModel 
{ 
    MySelectList = new SelectList(myCollection, "Id", "Name") 
}; 

在剃须刀视图中,您可以设置@Html。DropDownListFor像这样:

@Html.DropDownListFor(m => m.Id, Model.MySelectList) 

为了选择值传递给视图的下拉列表只需使用的SelectList构造函数重载,使这个值传递:

new SelectList(myCollection, "Id", "Name", selectedValue) 
相关问题