【问题标题】:MVC4 Razor DisplayTemplate called, HTML generated, but not rendered to browser调用 MVC4 Razor DisplayTemplate,生成 HTML,但未呈现给浏览器
【发布时间】:2013-07-02 04:35:59
【问题描述】:

我有一个迭代集合并为集合中的每个元素调用DisplayFor() 的视图。

我需要手动迭代(而不是将集合传递给 DisplayFor),以便告诉模板是否应该在列表中绘制中断。列表中的项目将只有 2 种类型,由它们排序,所以我只需要显示一次这个中断。

找到并正确调用了我的模板。
我可以看到它正确生成的 HTML,即:DisplayFor().ToHtmlString()
我可以将此 HTML 设置为范围变量,即:var html = DisplayFor().ToHtmlString() ..
但是即使Html.Raw(html) 也不会在浏览器中呈现它——HTML 已经完全消失了。

发生了什么事?

var renderBreakInList = Model.Items.Any(x => x.IsSomeType);
foreach(var item in Model.Items)
{
    var renderBreak = renderBreakInList && item.IsOtherType;
    Html.DisplayFor(x => item, new { renderBreak = renderBreak });

    if (renderBreak)
    {
        renderBreakInList = false;
    }
}

【问题讨论】:

  • 您的示例代码看起来很奇怪...DisplayFor 应该是Html.DisplayFor...您能发布您的实际代码吗?顺便说一下,电话@Html.DisplayFor(x => item, new { renderBreak = renderBreak }); 应该可以工作......
  • 是的,你是对的,它有 Html. 只是忘记在转置时添加它
  • 仍然缺少@ 符号...您尝试过@Html.DisplayFor(x => item, new { renderBreak = renderBreak }); 吗?

标签: asp.net-mvc-4 razor display-templates


【解决方案1】:

Html.DisplayFor 方法本身不会向响应呈现任何内容,只是将生成的 HTML 作为MvcHtmlString 返回。

为了将呈现的 HTML 实际写入响应,您需要使用 @ 符号将此告知 Razor:

@Html.DisplayFor(x => item, new { renderBreak = renderBreak })

所以你的整个代码应该是这样的:

@{
    var renderBreakInList = Model.Items.Any(x => x.IsSomeType);
    foreach(var item in Model.Items)
    {
        var renderBreak = renderBreakInList && item.IsOtherType;
        @Html.DisplayFor(x => item, new { renderBreak = renderBreak })

        if (renderBreak)
        {
            renderBreakInList = false;
        }
    }
}

或者您可以使用WebPageBase.Write 方法(使用@ 符号时会在后台调用):

Write(Html.DisplayFor(x => item, new { renderBreak = renderBreak }));

【讨论】:

  • 哦,笨蛋。没想到你已经回答了这个问题。厄运&谢谢!我花了一段时间才发现 sometimes 你需要在代码块中添加 @ 的东西,而其他时候你不能 - 我只是养成了习惯不这样做是为了避免“您不需要代码块内的@”错误。我假设它会给我它并在它前面放置一个display: none;跨度然后添加了@来让它工作。愚蠢的我..你赢得了答案,尽管它使我的模板不那么健壮,但我更喜欢只传递 itemID 以中断的代码的简洁外观:P
【解决方案2】:

在尝试了很多不同的事情并重新设计了我告诉模板绘制中断的方式后,终于弄清楚了这一点。

我不是发送一个我希望使模板更健壮的布尔值(如果订单发生变化),而是传递应该绘制中断的项目的 ID。

@{ 
    var breakItem = Model.Items.FirstOrDefault(x => renderBreakInList && x.IsSomeType);
    var breakID = breakItem == null ? (long?)null : (long)breakItem.ID;
}

@Html.DisplayFor(x => x.Items, new { breakID = breakID })    

就像 nemesv 指出的那样,Html.DisplayFor() 需要在前面加上 @。我改掉了在代码块中执行此操作的习惯,因为我总是会在代码块中得到'once you don't need @` 错误..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多