0

管理者が設定したトピックにユーザーが投票できる単純な Web アプリケーションを構築しています。各トピックには、2 つ以上のオプションを含めることができます。たとえば、「はい」または「いいえ」スタイルの投票トピックには、「ケンジントンで最高のレストランはどこですか?」という投票トピックとして 2 つのオプションがあります。多くのオプションを持つことができます。

これが私の現在の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 つのオプションが表示されているので、ここから始めます。スクリーンショットは次のとおりです。

ここに画像の説明を入力

最初の 2 つのボックスは正常に結合されますが、[オプションの追加] ボタンをクリックした後に動的に追加される 3 番目のボックスは結合されません!

私は何を間違っていますか?インデックス作成が正しいことを確認しましたが、機能していません:(

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 が自動的に生成されるため、バインディングは問題ありません。(すべてをサーバーに送信して削除することもできます)

id/name フィールドを JavaScript で手動で処理するか、サーバーから自動的に処理するかによって異なります。

于 2013-05-29T22:13:04.137 に答える