【问题标题】:Posting a collection - is empty/null when adding a class on the table row发布集合 - 在表格行上添加类时为空/null
【发布时间】:2018-07-27 11:37:15
【问题描述】:

我有一个简单的 ASP.NET MVC 应用程序,我们的用户有一个表格,其中有一些选项可以编辑一些设置。

此表是使用 jQuery 动态构建的,因为这是一些遗留代码。制作表格的代码是:

function setInvoiceTable(result) {
        result.OverduesPaged.forEach(function (item, index) {

            var externalName = 'OverduesPaged[' + index + '].ExternalInvoiceGuid';
            var debtorName = 'OverduesPaged[' + index + '].Debtor';
            var visibleName = 'OverduesPaged[' + index + '].IsSelected';

            var externalInvoiceGuidField = '<input type=\'hidden\' value=\'' + item.ExternalInvoiceGuid + '\' name=\'' + externalName+ '\' />';
            var debtorField = '<input type=\'hidden\' value=\'' + item.Debtor + '\' name=\'' + debtorName + '\' />';
            var invisibleField = '<input type=\'hidden\' value=\'false\' name=\'' + visibleName + '\' id=\'' + visibleName + '\' /></label>';
            var visibleField = '<label><input type=\'checkbox\' value=\'true\' name=\'' + visibleName + '\' id=\'' + visibleName + '\' />  Start sag';

            var insertStr = "<tr>" +
                "<td>" + externalInvoiceGuidField + debtorField + visibleField + invisibleField + "</td>" +
                "<td>" + item.InvoiceId + "</td>" +
                "<td>" + item.Debtor + "</td>" +
                "<td>" + item.DateString +"</td>" +
                "<td>" + item.DaysSinceDueString +"</td>" +
                "<td>" + item.GrossAmountString + "</td>" +
                "<td>" + item.RemainderAmountString + "</td>" +
                "</tr>";
            $('#accounting_invoices_table').append(insertStr);
        });
    }

当我发布时,这对我们来说非常有效。我们的控制器中有一个端点,它具有以下签名:

[System.Web.Mvc.HttpPost]
public ActionResult StartDebtCollectionCases(UpcomingDashboardViewModel vm)
{
    // code
}

我正在构建的集合是 OverduesPaged,它是我们视图模型的一部分:

public class UpcomingDashboardViewModel
{
    public List<OverdueUpcomingInvoiceViewModel> OverduesPaged { get; set; }
    // more stuff not relevant to question
}

这是我的挑战

我在&lt;tr&gt; 行中添加了一个css 类,如下所示:

            // new code added
            var removeClass = 'ok';
            if (item.IsAlreadyCase) {
                visibleField = '<label type="text">Allerede startet</label>';
                removeClass = 'remove';
            } else if (item.IsBlocked) {
                visibleField = '<label type="text">Sat i bero</label>';
                removeClass = 'remove';
            }
            else if (item.Currency != "DKK") {
                visibleField = '<label type="text">Faktura skal være dansk valuta</label>';
                removeClass = 'remove';
            }

            var insertStr = "<tr class='" + removeClass + "'>" +
                "<td>" + externalInvoiceGuidField + debtorField + visibleField + invisibleField + "</td>" +
            // rest of code from above

现在我最终得到了一个与以前完全相同的表,但具有一个 OK 或 REMOVE 的类。

但是,当我现在执行 POST 时,整个集合 OverduesPaged 为空/空:

我尝试将类添加到 &lt;td&gt;,但随后集合为空/空。

有什么想法吗?

【问题讨论】:

  • 注意相关,但这是生成 html 的一种脆弱/容易出错的方式。考虑一个使用 jQuery 克隆和更新的模板(类似于 this answer
  • @StephenMuecke 像这样创建它完全是公牛,而且在我们说话的时候它正在被重写:) 但是,我只是试图以一种快速/肮脏的方式实现这个 hack,不明白为什么这不起作用
  • 我假设因为如果你执行任何if 语句,那么visibleField 不再是&lt;input&gt;,它是&lt;label&gt; - 它也有一个无效的type="text" 属性)
  • 请注意您的id 属性也无效(包含[]. 字符(HtmlHelper 方法将这些字符替换为_)。而你在最初的var visibleField = ...中错过了结束&lt;/label&gt;
  • @StephenMuecke 你是对的。在标签内添加输入是有效的.. 所以我们现在很成功:) 现在我们只需要期待重新编写这个疯狂的代码:-D 想要回答吗?那我*会奖励它!

标签: asp.net .net asp.net-mvc


【解决方案1】:

问题与添加类名本身无关,而是在执行 ifelse if 块中的代码的 ant 时生成的无效 html。在这些块中,您正在创建带有结束标记的 &lt;label&gt; 元素,但没有输入(不清楚在这些情况下是否需要复选框),因此当您组合 visibleField + invisibleField 时,您会得到不平衡的 &lt;label&gt; 标签(@ 987654326@ 有开始和结束标签,但invisibleField 只有一个结束&lt;/label&gt; 标签。

您在 if 块中生成 visibleField 的代码需要与您在原始代码中生成的类似 - 即只是一个带有复选框的 HTML 开头的 &lt;label&gt;

正如您在 cmets 中所承认的,这是非常脆弱且容易出错的代码,难以调试。当您打算重写它时,请考虑在您的 ajax 调用中返回部分视图(与模型紧密绑定),或者如果您需要返回 Json,则考虑使用隐藏模板(在 &lt;form&gt; 标记之外)例如,您在脚本中克隆和更新

<div id="newrow" style="display:none">
    <tr>
        <td>
            <input class="invoice" type="hidden" name="OverduesPaged[#].ExternalInvoiceGuid value />
            <input class="debtor" type="hidden" name="OverduesPaged[#].Debtor value />
            ....
        </td>
        ....
    </tr>
</div>

然后你的脚本就变成了

var table = $('#accounting_invoices_table');
result.OverduesPaged.forEach(function (item, index) {
    var clone = $('#newrow').clone();
    // Update indexer
    clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
    // Update values
    clone.find('.invoice').val(item.ExternalInvoiceGuid);
    ....
    table.append(clone.html());
});

附带说明一下,您现有的 id 属性是无效的,因为它们包含 .[] 字符(如果您尝试在 jQuery 选择器中使用这些字符,它们会失败(例如 @ 987654340@ 将被解释为类名),因此它们应在 html 中省略

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-20
    • 2010-09-06
    • 2016-02-13
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    相关资源
    最近更新 更多