0

我正在构建一个简单的 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的回答,我已经设法绑定了非动态生成的输入,但是我的动态生成的输入由于某种原因没有被绑定!

这是创建选项输入字段的 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 个选项。这是一个屏幕截图:

在此处输入图像描述

前两个框绑定得很好,但是单击[添加选项]按钮后动态添加的第三个框没有!

我究竟做错了什么?我已确保索引正确,但它不起作用:(

4

1 回答 1

2

使用 for 循环遍历列表并使用 index 和 editorfor。

// 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 字段,还是从服务器自动处理。

于 2013-05-29T22:13:04.137 回答