如何以动态形式使用模型
Posted
技术标签:
【中文标题】如何以动态形式使用模型【英文标题】: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>
任何建议都会有所帮助。谢谢。
【问题讨论】:
【参考方案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<string> 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<Subject>
。
仅当您的控件具有name="Subjects[0].Subject"
、name="Subjects[1].Subject"
等时(索引器必须从零开始并且是连续的)。但是你不应该在视图中使用数据模型,尤其是在编辑时,所以它应该是无关紧要的
@Mairaj,糟糕 - 忘记添加链接了 :) 但在这种情况下,这样做会很麻烦
@StephenMuecke 是的,这就是我所期待的。现在我浏览了另一个链接,这对我来说看起来更容易techiesweb.net/2012/09/17/…以上是关于如何以动态形式使用模型的主要内容,如果未能解决你的问题,请参考以下文章
如何使用react-js以动态形式将复选框值与文本输入绑定?