简体   繁体   English

ASP.NET MVC的Create View中的集合的数据绑定

[英]Data-binding for collections in Create View of ASP.NET MVC

I'm trying to add a survey feature to my ASP.NET MVC 5 web application so that users can create surveys with custom questions to send out to other users. 我正在尝试将调查功能添加到我的ASP.NET MVC 5 Web应用程序中,以便用户可以创建带有自定义问题的调查以发送给其他用户。 The problem is, I'm having trouble allowing users to add questions to the survey on the Create Survey view. 问题是,我无法允许用户在“创建调查”视图中向调查添加问题。

I've seen ways to do this on the "Edit" View, when an instance of the model has already been created, but I want the user to be able to create questions on the survey before adding the survey to the database. 我已经看到了在“编辑”视图中执行此操作的方法,当已经创建了模型的实例时,但我希望用户能够在将调查添加到数据库之前创建调查问题。

This is my Survey Model: 这是我的调查模型:

public class Survey
    {
        public int SurveyId { get; set; }

        public string Name { get; set; }

        public string Author { get; set; }

        public DateTime StartDate { get; set; }

        public DateTime EndDate { get; set; }

        public List<Question> Questions { get; set; }

        public List<Response> Responses { get; set; }
    }

and this is my Question model: 这是我的问题模型:

public class Question
    {
        public int QuestionId { get; set; }

        public int SurveyId { get; set; }

        public string Title { get; set; }

        public string Body { get; set; }

        public QuestionType QuestionType { get; set; }

        public DateTime CreatedOn { get; set; }

        public DateTime LastModified { get; set; }

        public List<Answer> Answers { get; set; }
    }

Honestly, the code I have right now in Create.cshtml is garbage because I don't really know where to start but here it is anyways: 老实说,我现在在Create.cshtml中的代码是垃圾,因为我真的不知道从哪里开始,但在这里它是无论如何:

<h2>Create</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Survey</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Author, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Author, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Author, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.StartDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.StartDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.StartDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.EndDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.EndDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.EndDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <h4 class="well well-small">
            Questions
        </h4>

        <button class="toggle-add-question" data-target="#add-question" data-toggle="modal" type="button">
            <i class="icon-plus"></i> Add Question
        </button>

        <div class="modal" id="add-question" tabindex="-1">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h3>Add Question</h3>
            </div>
            <div class="modal-body">
                <div class="row">
                    <form method="post">
                        <fieldset>
                            <div class="form-group">
                                <label for="Title">Title</label>
                                <input type="text" id="Title" name="Title" data-bind="value: title" />
                            </div>
                            <div class="form-group">
                                <label for="Type">Type</label>
                                <select id="Type" name="Type" data-bind="value: type">
                                    <option>Yes/No</option>
                                    <option>Number</option>
                                </select>
                            </div>
                        </fieldset>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <input type="submit" value="Create" class="btn btn-default" data-dismiss="modal" />
                            </div>
                        </div>
                    </form>
                </div>
                <div class="row">
                    <div class="span6">
                        <textarea id="Body" name="Body"></textarea>
                    </div>
                </div>
            </div>
        </div>

        <table class="table">
            <tr>
                <th>
                    Question Title
                </th>
                <th>
                    Question Body
                </th>
                <th>
                    Question Type
                </th>
            </tr>
            @if (Model.Questions != null)
            {
                for (var i = 0; i < Model.Questions.Count(); i++)
                {
                    <tr>
                        @Html.HiddenFor(x => Model.Questions[i].QuestionId)
                        <td>
                            @Html.TextBoxFor(x => Model.Questions[i].Title)
                        </td>
                        <td>
                            @Html.TextBoxFor(x => Model.Questions[i].Body)
                        </td>
                        <td>
                            @Html.TextBoxFor(x => Model.Questions[i].QuestionType)
                        </td>
                    </tr>
                }
            }
        </table>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

What I want is for the user to be able to click the "Add Question" button, have the modal with the question fields pop up, and then for the user to be able to click "save" and have the modal exit and the new question appear in the table. 我想要的是让用户能够点击“添加问题”按钮,弹出带有问题字段的模态,然后让用户能够点击“保存”并拥有模态退出和新问题出现在表格中。 Right now, I'm getting the error that the object reference is not set to an instance of the object, which makes perfect sense because the Survey object hasn't been created yet, but I'm unsure of how to do this differently. 现在,我得到的错误是对象引用未设置为对象的实例,这非常有意义,因为尚未创建Survey对象,但我不确定如何以不同方式执行此操作。 (Without the table, the modal view pops up and everything but no questions are added). (没有表格,弹出模态视图,但不添加任何问题)。

Any help would be greatly appreciated, thanks! 任何帮助将不胜感激,谢谢!

You could update the table, when saving the modal popup by combining AJAX and Partial Views (called partials from here on). 通过组合AJAX和部分视图(此处称为部分视图)保存模式弹出窗口时,您可以更新表格。

The table that holds your question data could sit in a partial with its own view model that takes in the questions you want to render. 包含您的问题数据的表可能位于具有自己的视图模型的部分中,该模型接收您要呈现的问题。 You can keep the markup as is. 您可以按原样保留标记。

On your page, where the table is now, replace that with a containing div that has the partial inside. 在您的页面上,表格现在,将其替换为包含部分内部的div。

When you save the modal that adds a new question, you could use an AJAX call (trigger on click) to hit your Controller, save the new question record (with whatever validation you need) and return the table partial with a new view model, populated with the questions in your DB (which would include the new you just saved). 保存添加新问题的模态时,可以使用AJAX调用(单击时触发)命中Controller,保存新问题记录(使用您需要的任何验证)并使用新视图模型返回表部分,填充了数据库中的问题(包括您刚刚保存的新内容)。

In the success callback of the AJAX call, populate the container div with the new partial and view model, then close the popup. 在AJAX调用的成功回调中,使用新的partial和view模型填充容器div,然后关闭弹出窗口。 The page will show a new question in the table without having go through a whole page cycle. 该页面将在表格中显示一个新问题,而不会经历整个页面循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM