【问题标题】:How to use model in dynamic form如何以动态形式使用模型
【发布时间】:2017-06-20 09:14:33
【问题描述】:

场景:

用户可以输入他/她的姓名、年级和导师姓名。然后需要输入主题标记。主题表单字段是动态的,也就是说,一个用户可能有 5 个主题,而另一个用户可能只有 3 个。

当前修复:

目前,我已经用意大利面条代码修复了这个问题,在按钮点击事件上使用了 jQuery 的append。并将表单数据作为 FormCollection 传递,然后将 formcollection 更改为模型。

我需要什么:

我需要使用模型而不是表单集合。也就是说,我需要将表单数据作为模型而不是表单集合传递。

这是我所做的:

型号:

public class StudentModel
{
    public string Name { get; set; }
    public string Grade { get; set; }
    public string Tutor { get; set; }
    public List<SubjectModel> Subjects { get; set; }
}

public class SubjectModel
{
    public string Subject { get; set; }
}

控制器:

public class HomeController : Controller
{
    ....
    [HttpPost]
    public ActionResult Index(FormCollection form)
    {
        var subjects = form["Subject"].Split(',');
        var modelsubjects = new List<SubjectModel>();
        foreach (var subject in subjects)
        {
            modelsubjects.Add(new SubjectModel() { Subject = subject });
        }

        var model = new StudentModel();
        model.Name = form["Name"];
        model.Grade = form["Grade"];
        model.Tutor = form["Tutor"];
        model.Subjects = modelsubjects;

        //Here I get the model from a dynamic form

        return View();
    }
}

查看:

<div class="jumbotron">
    @using (Html.BeginForm("Index", "Home", FormMethod.Post))
    {
        <div class="row">
            <div class="col-sm-3">
                <label for="Name">Name</label>
                <input type="text" id="Name" name="Name" />
            </div>
            <div class="col-sm-3">
                <label for="Grade">Grade</label>
                <input type="text" id="Grade" name="Grade" />
            </div>
            <div class="col-sm-3">
                <label for="Tutor">Tutor</label>
                <input type="text" id="Tutor" name="Tutor" />
            </div>
            <div class="col-sm-1">
                <a class="btn btn-primary" id="addSubject">Add Subject</a>
            </div>
            <div class="col-sm-1">
                <input class="btn btn-primary" type="submit" value="Submit" />
            </div>
        </div>
        <div id="subjectInfo" style="padding-top:10px;">
        </div>
    }
</div>

<script type="text/javascript">
    var count = 0;
    $("#addSubject").click(function () {
        $("#subjectInfo").append("<div class='row'>" +
                "<div class='col-sm-8'>" +
                    "<label for='Subject_" + count + "'>Subject " + count + "</label>" +
                    "<input type='text' name='Subject' id='Subject_" + count + "' />" +
                "</div>" +
            "</div>");
        count++;
    });
</script>

任何建议都会有所帮助。谢谢。

【问题讨论】:

    标签: javascript c# jquery asp.net-mvc forms


    【解决方案1】:

    我想你期待这个解决方案

    型号:

     public class StudentModel
        {
            [Required]
            public string Name { get; set; }
            public string Grade { get; set; }
            public string Tutor { get; set; }
            public List<SubjectModel> Subjects { get; set; }
        }
    
        public class SubjectModel
        {
            [Required]
            public string Subject { get; set; }
        }
    

    控制器:

     public class HomeController : Controller
        {
            ....
    
            [HttpPost]
            public ActionResult Index(StudentModel stu)
            {            
                if (ModelState.IsValid)
                {
                    //db operations
                    return RedirectToAction("Index");
                }
                return View(stu);
            }
            public ActionResult Subjects(int count)
            {
                ViewBag.count = count;
                return PartialView("SubjectPV");
            }
    

    查看:

    @{
        ViewBag.Title = "Index";
    }
    @model DynamicModelForm.Models.StudentModel
    <div class="jumbotron">
        @using (Html.BeginForm("Index", "Home", FormMethod.Post))
        {
            <div class="row">
                <div class="col-sm-3">
                    <label for="Name">Name</label>
                    @*<input type="text" id="Name" name="Name" />*@
                    @Html.TextBoxFor(x => x.Name)
                    @Html.ValidationMessageFor(x => x.Name)
                </div>
                <div class="col-sm-3">
                    <label for="Grade">Grade</label>
                    @*<input type="text" id="Grade" name="Grade" />*@
                    @Html.TextBoxFor(x => x.Grade)
                </div>
                <div class="col-sm-3">
                    <label for="Tutor">Tutor</label>
                    @*<input type="text" id="Tutor" name="Tutor" />*@
                    @Html.TextBoxFor(x => x.Tutor)
                </div>
                <div class="col-sm-1">
                    <a class="btn btn-primary" id="addSubject">Add Subject</a>
                </div>
                <div class="col-sm-1">
                    <input class="btn btn-primary" type="submit" value="Submit" />
                </div>
            </div>
            <div id="subjectInfo" style="padding-top:10px;">
                @{
                    if (Model.Subjects != null)
                    {
                        var count = 0;
                        foreach (var sub in Model.Subjects)
                        {
                            <div class='row'>
                                <div class='col-sm-8'>
                                    <label for="Subject_@count">Subject @count</label>
                                    @*@Html.TextBoxFor(x => x.Subject, new { id = "subject_" + count })*@
                                    <input type="text" class="SubjectsSubject" name="Subjects[@count].Subject" id="subject_@count" value="@sub.Subject" />
                                    @Html.ValidationMessageFor(x => x.Subjects[count].Subject)                                
                                </div>
                            </div>
                            count++;
                        }
                    }
                }
            </div>
                    }
    </div>
    
    <script type="text/javascript">
        //var count = 0;
        $("#addSubject").click(function () {
            var count = $('.SubjectsSubject').length
            $.ajax({
                url: '@Url.Action("Subjects","Home")' + "?count=" + count,
                success: function (result) {
                    $("#subjectInfo").append(result);
                    //count++;
                },
                error: function (req, status, error) {
                    alert(error);
                }
            });
        });
    </script>
    

    动态部分视图:

    @model DynamicModelForm.Models.SubjectModel
    
        <div class='row'>
            @{
                var count = ViewBag.count;
            }
            <div class='col-sm-8'>
                <label for="Subject_@count">Subject @count</label>
                @*@Html.TextBoxFor(x => x.Subject, new { id = "subject_" + count })*@
                <input type="text" class="SubjectsSubject" name="Subjects[@count].Subject" id="subject_@count"/>
                @Html.ValidationMessageFor(x => x.Subject)
                @*<span class="field-validation-valid" data-valmsg-for="Subjects[@count].Subject" data-valmsg-replace="true"></span>*@
            </div>
        </div>
    

    在 github 中完成项目

    https://github.com/rajsram/DynamicModelForms

    【讨论】:

      【解决方案2】:

      由于SubjectModel 只包含一个简单的属性,那么如果您只使用包含属性List&lt;string&gt; Subjects 的视图模型然后您的输入只需要具有`

      public class StudentVM
      {
          public string Name { get; set; }
          public string Grade { get; set; }
          public string Tutor { get; set; }
          public List<string> Subjects { get; set; }
      }
      

      Subjects 属性将是文本框值的数组,然后您可以在 POST 方法中映射到您的数据模型

      [HttpPost]
      public ActionResult Index(StudentVM model)
      {
          var student = new StudentModel();
          student.Name = model.Name;
          ....
          foreach (var subject in model.Subjects)
          {         
              student.Subjects.Add(new SubjectModel() { Subject = subject });
          }
          // Save and redirect
      

      如果SubjectModel 包含多个属性,那么您需要生成带有名称前缀和索引器的输入(请参阅this answer 了解某些选项)

      旁注:您应该使用强类型 HtmlHelper 方法生成输入,以便获得正确的 2-way 模型绑定以及客户端和服务器端验证。

      @Html.LabelFor(m => m.Name)
      @Html.TextBoxFor(m => m.Name)
      @Html.ValidationMessageFor(m => m.Name)
      

      【讨论】:

      • 感谢您的回复。有什么办法只使用StudentModel 而不是StudentVM?
      • @Stephen Muecke 我认为OP希望如何将动态生成的字段绑定到模型中的List&lt;Subject&gt;。
      • 仅当您的控件具有name="Subjects[0].Subject"、name="Subjects[1].Subject" 等时(索引器必须从零开始并且是连续的)。但是你不应该在视图中使用数据模型,尤其是在编辑时,所以它应该是无关紧要的
      • @Mairaj,糟糕 - 忘记添加链接了 :) 但在这种情况下,这样做会很麻烦
      • @StephenMuecke 是的,这就是我所期待的。现在我浏览了另一个链接,这对我来说看起来更容易techiesweb.net/2012/09/17/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      相关资源
      最近更新 更多