【问题标题】:EditorFor Field for List object that maps to a different model?映射到不同模型的 List 对象的 EditorFor 字段?
【发布时间】:2015-04-23 01:24:12
【问题描述】:

在我看来,我有一个fieldset,用户可以在其中创建一个帖子我有一个Tags 的列表,可以在创建时选择并在我的EF 中与@987654324 的多对多关系中关联@,这会在保存帖子时在PostTagMap 中创建PostTag 之间的关系。但是,我想在视图中添加一个额外的字段,以便用户还可以“创建”一个标签(输入名称)以及选择标签,但是我无法弄清楚我的 jQuery 中的最后一个问题以使其工作。

查看:

@model MyBlogger.Models.Post
@using(Html.BeginForm())
{
  // controls for Post
  ....
  <div id="tags">
    for (int i = 0; i < tag.Count; i++)
    {
      var id = string.Format("tag{0}", tag[i].Id);
      var isChecked = tag[i].IsAssigned ? "checked" : null;
      <div class="tag">
        <input id="@id" type="checkbox" name="selectedTags" value="@tag[i].Id" @isChecked />
        <label for="@id">@tag[i].Name</label>
      </div>
    }
  </div>
  <button id="addtag" type="button">Add new tag</button>
  <div id="dialog" style="display:none">
  @Html.Action("CreateTag")
}

后控制器:

// Returns a partial view with a form to create a new Tag
[ChildActionOnly]
public ActionResult CreateTag()
{
  Tag model = new Tag();
  return PartialView(model);
}

[HttpPost]
public ActionResult CreateTag(Tag model)
{
  // Save the Tag
  db.Tags.Add(model);
  db.SaveChanges();
  return Json(new { ID = model.Id, Name = model.Name });
}

局部视图:

@model MyBlogger.Models.Tag
@using(Html.BeginForm())
{
  // controls for Tag
  ....
  <button id="createtag" type="button">Create</button>
}

后控制器

[ChildActionOnly]
public ActionResult CreateTag()
{
  Tag model = new Tag();
  return PartialView(model);
}

[HttpPost]
public ActionResult CreateTag(Tag model)
{
  // Save the Tag
  db.Tags.Add(model);
  db.SaveChanges();
  return Json(new { ID = model.Id, Name = model.Name });
}

脚本

var dialog = $('#dialog');
var tags = $('#tags');
var url = '@Url.Action("CreateTag")';
$('#addtag').click(function() {
  dialog.show();
});
$('#createtag').click(function() {
  var form = $(this).closest('form');
  $.post(url, form.serialize(), function(data) {
    if(data) {
      var id = tags.children('.tag').length;
      var div = $('<div></div>').addClass('tag');
      .... stuck here
      div.append($('<label></label>').attr('for', id).text(data.Name));
      tags.append(div);
      form.get(0).reset(); // reset controls to their defaults
      dialog.hide(); // hide the dialog
    }

【问题讨论】:

  • 最好使用弹出表单来创建新标签,然后使用 ajax 将其发布到控制器,控制器保存并返回 json 指示其新 id 和显示名称,并使用它来更新 DOM带有一个新的复选框
  • 给我一两个小时来完成我的工作,我会给你一个简化的例子。但是您确实需要开始使用视图模型来表示您要编辑的内容:)
  • 因为它是正确的方法。您只是还没有意识到您可能面临的问题,尤其是当您开始向您的属性添加验证属性时。然后当然存在过度发布攻击的问题。如果您使用 automapper 等工具,将视图模型映射到数据模型(反之亦然)很容易。仅此@Html.HiddenFor(model =&gt; model.BlogUserEmail, User.Identity.Name) 就是一个问题。您不应该在视图中包含它,而是在保存对象时在 POST 方法中设置它的值。

标签: c# sql asp.net-mvc linq


【解决方案1】:

在你的控制器中创建额外的方法来创建一个新的Tag

后控制器

// Returns a partial view with a form to create a new Tag
[ChildActionOnly]
public ActionResult CreateTag()
{
  Tag model = new Tag();
  return PartialView(model);
}

[HttpPost]
public ActionResult CreateTag(Tag model)
{
  // Save the Tag
  db.Tags.Add(model);
  db.SaveChanges();
  return Json(new { ID = model.Id, Name = model.Name });
}

局部视图

@model MyBlogger.Models.Tag
@using(Html.BeginForm())
{
  // controls for Tag
  ....
  <button id="createtag" type="button">Create</button>
}

主视图

@model MyBlogger.Models.Post
@using(Html.BeginForm())
{
  // controls for Post
  ....
  <div id="tags">
    // not sure what you trying to do with you existing code, but
    for (int i = 0; i < tag.Count; i++)
    {
      var id = string.Format("tag{0}", tag[i].Id);
      var isChecked = tag[i].IsAssigned ? "checked" : null;
      <div class="tag">
        <input id="@id" type="checkbox" name="selectedTags" value="@tag[i].Id" @isChecked />
        <label for="@id">@tag[i].Name</label>
      </div>
    }
  </div>
  <button id="addtag" type="button">Add new tag</button>
  ....
}
<div id="dialog" style="display:none">
  @Html.Action("CreateTag")
</div> // outside main form tags!

脚本

var dialog = $('#dialog');
var tags = $('#tags');
var url = '@Url.Action("CreateTag")';
$('#addtag').click(function() {
  dialog.show();
});
$('#createtag').click(function() {
  var form = $(this).closest('form');
  $.post(url, form.serialize(), function(data) {
    if(data) {
      var id = tags.children('.tag').length;
      var div = $('<div></div>').addClass('tag');
      div.append($('<input/>').val(data.ID).attr({ type: 'checkbox', name: 'selectedTags', id: id }).prop('checked', true));
      div.append($('<label></label>').attr('for', id).text(data.Name));
      tags.append(div);
      form.get(0).reset(); // reset controls to their defaults
      dialog.hide(); // hide the dialog
    }
  });
});

请参阅 this fiddle 以获取有关如何设置对话框和标签复选框及其标签样式的示例

旁注:

  1. 我强烈建议您开始只使用视图模型来表示 您需要在视图中显示/编辑的属性。
  2. 表格用于表格数据,而不是布局。

【讨论】:

猜你喜欢
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 2018-01-05
  • 2020-04-21
相关资源
最近更新 更多