gpt4 book ai didi

jquery - 如何动态创建/删除元素并允许模型绑定(bind)启动?

转载 作者:行者123 更新时间:2023-12-01 01:54:50 24 4
gpt4 key购买 nike

我过去曾经这样做过,我可能必须再做一次,但在我这样做之前,我想把它扔出去看看人们如何处理它。

Razor View :

<ul>
@Html.EditorFor(model => model.Questions)
</ul>

这可以产生:

<ul>
<li><input type="text" id="Questions_0__Title" name="Questions[0].Title" value="hi"/></li>
<li><input type="text" id="Questions_1__Title" name="Questions[1].Title" value="hi2"/></li>
<ul>

非常简单。

现在,我需要允许用户添加、编辑或删除任何这些“问题”。

对于编辑来说,这很简单 - 无需任何工作。但是对于添加/删除,如果我用 jQuery 来做,我需要聪明地了解生成“id”和“name”属性的方式(例如,计算有多少个,添加 1 等) ),对于删除,我将“重新渲染”一些元素(例如,如果删除了一个元素,我需要将所有后续元素的“id”和“name”属性更改为-1)。

所有这一切都是因为它是一个表单,并且需要模型绑定(bind)。

这对我来说太毛茸茸的,所以过去,我用表单上的任何内容对服务器进行了 AJAX 调用,然后在 Controller 中添加/删除元素,并渲染一个局部 View 。这样,所有元素都“准备好进行模型绑定(bind)”。我仍然需要一点 jQuery,但远没有那么多。

有没有人找到更好的方法?

最佳答案

我也必须处理完全相同的情况。我想出的最简单的解决方案是使用包装器模型,类似于:

public class QuestionListModel
{
public IList<QuestionModel> Questions { get; set; }

public IList<QuestionModel> Template
{
get
{
return new List<QuestionModel>
{
new QuestionModel {/* defaults for new question */}
};
}
}

public QuestionListModel()
{
Questions = new List<QuestionModel>();
}
}

重要的部分是拥有 Template 属性,它也是一个 IEnumerable<T>与您想要的实际型号相同的类型。这样,MVC 就会为您完成自动编号。因此,使用此模型,您得到的是带有“Questions_0__Title”编号的集合,并且您还获得一个带有“Template_0__Title”命名的模板行。

我将模板行从 UI 中隐藏起来,并在添加新行时使用它。

在 razor 中,您可以像绑定(bind)常规问题一样绑定(bind)模板,唯一的区别是它位于隐藏的 <div> 中。 。您还需要绑定(bind) Count您的问题列表也将添加到隐藏字段。就我而言,我有一个问题的编辑器模板,它将其呈现在 <div> 中。具有特定的选择器,以便以后轻松访问。所以你最终得到的结果类似于:

<div class="templateContainer">
<div class="question">
[Template]
</div>
</div>
<div class="items">
[for each of your items]
<div class="question">
[Question]
</div>
</div>

添加行时,技巧是使用 javascript:

  1. 从隐藏字段获取计数,并递增它。

        var counter = $("#QuestionsListCount");
    var count = parseInt(counter.val());
    count++;
  2. 获取整个模板 block ,克隆它(例如使用 jquery 的 .clone(true)),将其命名为唯一的名称(例如使用步骤 1 中的计数器值),并将其附加到您的问题所在的部分是。

        var template = $("#templateContainer");
    var newItem = template.clone(true);
    var newId = "item_" + count;
    var newQuestion = newItem.children().first();
    newQuestion.attr("id", newId);
    newQuestion.appendTo('#items');
  3. 对于每个项目,例如新附加 block 中的输入(您可以使用分配给它的新 ID 找到它),将 ids => "Template_0"替换为 "Questions__count from step 2",然后名称 =>“模板[0]”和“问题[第 2 步中的计数]”。

        $("#" + newId + " :input").each(function (index, input) {
    input.id = input.id.replace("Template_0", "Questions_" + (count - 1));
    input.name = input.name.replace("Template[0]", "Questions[" + (count - 1) + "]");
    });
  4. 更新计数器的隐藏字段=> counter.val(count);

  5. ...
  6. 利润!

现在,关于删除,我的做法是,我的 ViewModel 实际上有一个 IsDeleted标志,我也将其绑定(bind)到问题编辑器模板中的隐藏字段。这样,删除就像隐藏特定问题一样简单(问题选择器很方便),然后您将其设置为 IsDeleted字段为真。当您通过默认模型绑定(bind)器取回整个列表时,您需要丢弃所有已删除的列表(或发出实际删除,具体取决于您的后端数据模型)。​​

这样,我就不必处理识别已删除项目的单独方法,也不必对 UI 中的所有项目重新编号。另外,您还可以利用服务器端代码来确定删除时实际发生的情况(例如验证或撤消操作)。

这是一篇很长的文章,但实现并不是那么困难(或很长),并且可以轻松地以通用方式重用。

干杯!

关于jquery - 如何动态创建/删除元素并允许模型绑定(bind)启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10579065/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com