我正在构建一个简单的Web应用程序,用户可以对管理员设置的主题进行投票。每个主题,可以有两个或更多选项,例如是或否样式投票主题,将有两个选项,其中作为“什么是肯辛顿最好的餐厅?”的投票主题。可以有很多选择。
这是我当前的ViewModel:
public class NewTopicVM
{
[Required]
[Display(Name = "Topic Title")]
public string TopicTitle { get; set; }
[Required]
[Display(Name = "Topic Description")]
public string TopicDescription { get; set; }
[Display(Name = "Topic Image")]
public byte[] TopicImage { get; set; }
public List<NewOptionVM> TopicOptions { get; set; }
}
public class NewOptionVM
{
public string OptTitle { get; set; }
public string OptDescription { get; set; }
}
请注意NewOptionVM
中的NewTopicVM
列表。感谢Iko的回答,我已经设法绑定非动态生成的输入,但是我动态生成的输入不会因某种原因而受到约束!
以下是创建Option输入字段的jQuery代码:
var index = 1;
function generateOptMarkup() {
var container = $('<div />');
var optionInputsBlock = $('<div />');
optionInputsBlock.addClass('optionInputsBlock');
var inputTitleBlock = $('<div />');
inputTitleBlock.addClass('inputBlock');
var inputDescBlock = $('<div />');
inputDescBlock.addClass('inputBlock');
var optTitleLbl = $('<label />');
optTitleLbl.attr('for', 'TopicOptions_' + ++index + '__OptTitle');
optTitleLbl.text('Option Title');
var optDescLbl = $('<label />');
optDescLbl.attr('for', 'TopicOptions_' + index + '__OptDescription');
optDescLbl.text('Option Description');
var optTitleInpt = $('<input type="text" />');
optTitleInpt.addClass('text-box single-line');
optTitleInpt.attr('name', 'TopicOptions_' + index + '__OptTitle');
optTitleInpt.attr('id', 'TopicOptions_' + index + '__OptTitle');
optTitleInpt.attr('data-val-required', 'The Option Title field is required.');
optTitleInpt.attr('data-val', 'true');
var optDescInpt = $('<input type="text" />');
optDescInpt.addClass('text-box single-line');
optDescInpt.attr('name', 'TopicOptions_' + index + '__OptDescription');
optDescInpt.attr('id', 'TopicOptions_' + index + '__OptDescription');
optDescInpt.attr('data-val-required', 'The Option Description field is required.');
optDescInpt.attr('data-val', 'true');
inputTitleBlock.append(optTitleLbl).append(optTitleInpt);
inputDescBlock.append(optDescLbl).append(optDescInpt);
optionInputsBlock.append(inputTitleBlock).append(inputDescBlock);
container.append(optionInputsBlock);
return container.html();
}
$('div.buttons > a').click(function () {
$('div.topicOptionsBlock').append(generateOptMarkup());
});
我从Index = 1
开始,因为我已经显示了2个选项。这是一个截图:
前两个框被绑定得很好,但是点击[添加选项]按钮后动态添加的第三个框没有!
我做错了什么?我确保索引是正确的,但它不起作用:(
答案 0 :(得分:2)
使用for循环遍历列表并使用索引和编辑器。
// other fields as usual
For(int i = 0; i < Model.TopicOptions.Count; i++)
{
@Html.EditorFor(m => m.TopicOptions[i].OptTitle)
@Html.EditorFor(m => m.TopicOptions[i].OptDescription)
}
MVC默认绑定现在会捕获它们。 如果你检查HTML MVC有一些格式来绑定它们,所以它就像TopicOptions__0_OptTitle。
在动作上放置一个断点,模型应该完全绑定,你不需要手动做任何事情。
编辑。 您可以将for循环的内部(2个editorFors)放在PartialView中,然后在调用它时通过ViewData传递索引。
for(...)
@Html.Partial("_NewOption", new ViewDataDictionary { { "index", i } })
现在,如果您动态添加新项目,则可以对操作进行ajax调用,以返回列表,其中最后一项是新对象。该操作应返回索引,然后绑定将正常,因为名称和ID将自动生成。 (您也可以将所有内容发送到服务器进行删除)
这取决于您是想在javascript中手动处理id / name字段,还是从服务器自动处理。