【问题标题】:How to make your views DRY with MVC5 and multiple page breakpoints?如何使用 MVC5 和多个页面断点使您的视图干燥?
【发布时间】:2016-11-03 16:15:48
【问题描述】:

我有一个困境,我不太确定如何克服。我不知道什么是正确的方法。我正在建立一个网站,并获得了一个模板来与我的服务器代码集成。问题在于模板的轮廓。让我给你举个例子。

<body>
    <div class="breakpoint active" id="bp_infinity" data-min-width="588">
        <div id="header">full page header content</div>
        <div id="body">some stuff</div>
        <div id="footer">some stuff</div>
    </div>
    <div class="breakpoint" id="bp_587" data-min-width="493" data-max-width="587">
        <div id="header">mobile header content</div>
        <div id="body">some stuff</div>
        <div id="footer">some stuff</div>
    </div>
    <div class="breakpoint" id="bp_492" data-max-width="492">
        <div id="header">mobile header content</div>
        <div id="body">some stuff</div>
        <div id="footer">some stuff</div>
    </div>
</body>

我正在尝试以不重复通用代码的方式设置我的 MVC5 视图。我面临的问题是页眉和页脚 div 是页面之间的通用代码,并且正文会发生变化。第二个问题是每个页面都有不同数量的断点。这是第二页来说明我的意思:

<body>
    <div class="breakpoint active" id="bp_infinity" data-min-width="588">
        <div id="header">full page header content</div>
        <div id="body">some stuff</div>
        <div id="footer">some stuff</div>
    </div>
    <div class="breakpoint" id="bp_587" data-max-width="587">
        <div id="header">mobile header content</div>
        <div id="body">some stuff</div>
        <div id="footer">some stuff</div>
    </div>
</body>

所以布局页面现在设置起来很棘手,因为我不能只说:

<body>
    @RenderBody
</body>

我想到的解决方案之一是使用 Sections,如下所示:

<body>
    @RenderBody
    @RenderSection("Breakpoint-1", false)
    @RenderSection("Breakpoint-2", false)
    @RenderSection("Breakpoint-3", false)
</body>

现在每一页都会是:

@section Breakpoint-1
{
    <div class="breakpoint active" id="bp_infinity" data-min-width="588">
        @{ Html.RenderPartial("full-page-header"); }
        @{ Html.RenderPartial("full-page-body"); }
        @{ Html.RenderPartial("full-page-footer"); }
    </div>
}
@section Breakpoint-2
{
    <div class="breakpoint" id="bp_587" data-max-width="587">
        @{ Html.RenderPartial("mobile-page-header"); }
        @{ Html.RenderPartial("mobile-page-body"); }
        @{ Html.RenderPartial("mobile-page-footer"); }
    </div>
}

我在上面的代码中看到的一个问题是,如果标题现在需要有 5 个断点而不是 2 个,我需要到处修改它。

有没有更好的方法来做到这一点?我认为最适合我的方案的解决方案是什么?

编辑:澄清。 HTML 中有多个制动点,因为一次只有一个是活动的。当页面达到一定宽度时, 1 当前活动断点被隐藏,新断点变为可见。

【问题讨论】:

  • 从最后一段来看,您似乎根据设备显示不同的数据,那么您为什么不只是检测设备/屏幕尺寸并仅渲染您需要的 html(生成 2-5 次为很多 html 只会降低性能)
  • 如果你真的想这样做,那么一个选择是创建一个 HtmlHelper 扩展方法,可以使用(比如)@Html.Breakpoint(header, body, footer, width) 调用,其中前 3 个参数是部分视图(typeof string)。该方法将输出&lt;div&gt; 和部分
  • @StephenMuecke 是一个响应式网站,所以它需要能够在桌面上切换大小。至于您的第二篇文章,这意味着我正在服务器端的字符串中构建我的 HTML。不知何故,感觉不对。
  • 是的,我知道 - 但您不需要根据需要向浏览器发送 5 倍的 html - 请参阅 this article。不知道你的第二条评论是什么意思 - 你已经在你的视图中使用HtmlHelper 方法(这些方法在服务器端的字符串中构建 HTML
  • 扩展方法意味着你所有的主视图需要渲染输出是@Html.Breakpoint("full-page-header", "full-page-body", "full-page-footer") @Html.Breakpoint("mobile-page-header", "mobile-page-body", "mobile-page-footer") ——我省略了最后一个参数——但它可能应该是一个enum,它允许你有条件地设置属性,比如如idmin-width

标签: asp.net asp.net-mvc razor asp.net-mvc-5 razor-2


【解决方案1】:

假设

……是万物之母……

  1. body 标签中的“一些东西”是从某个数据源提供的 HTML,或者是硬编码的
  2. “...页眉和页脚 div 是页面之间的通用代码...”的意思是,您根本不需要更改页眉/页脚。 (你仍然可以,但我暂时忽略了)
  3. div id 的“header”、“body”、“footer”应作为 dom 类而不是 dom id 处理。那是另一个讨论,但 id 应该始终是唯一的。

解决方案

这是一个基本示例,还有很多其他方法可以尝试,并且您可以进行很多其他调整

控制器 我们称之为 BreakpointController

public ActionResult Index()
{
  var model = new List<BreakpointViewModel>();
  // populate model
  return View(model);
}

视图模型

public class BreakpointViewModel
{
    public string BreakPointId { get; set; }
    public int? MinWidth { get; set; }
    public int? MaxWidth { get; set; }
    public string Body { get; set; }
    public bool IsActive { get; set; }
}

查看 这应该是你的index.cshtml(或者你想叫什么)

@model IEnumerable<WebApplication1.Models.BreakpointViewModel>

<div>
    <h1>A header!</h1>
</div>

@Html.DisplayForModel()

<div>
    <h4>A footer!</h4>
</div>

显示模板 * 你应该住在包含控制器(或共享)视图的文件夹中 * 你应该住在一个名为“DisplayTemplates”的子文件夹中 * 你应该被命名为 {ModelName}.cshtml

最后,文件夹结构应该是这样的:

Views
|-- Breakpoint
|   |-- DisplayTemplates
|   |   +-- BreakpointViewModel.cshtml
|   +-- Index.cshtml

BreakpointViewModel.cshtml 应该如下所示:

@model WebApplication1.Models.BreakpointViewModel

<div class="breakpoint @(Model.IsActive ? "active" : null)"
     id="@Model.BreakPointId"
     @(Model.MinWidth.HasValue ? "data-min-width='" + Model.MinWidth + "'" : null)
     @(Model.MaxWidth.HasValue ? "data-max-width='" + Model.MaxWidth + "'" : null)>
     @Html.Raw(Model.Body)
</div>

注意 div 中的 minwidth/maxwidth 行。不需要,只是我个人如何处理宽度。

生成的 HTML

<div>
    <h1>A header!</h1>
</div>

<div class="breakpoint active"
        id="bp_1"
        data-max-width=&#39;720&#39;>
    <div>Hello World!</div>
</div>

<div class="breakpoint"
        id="bp_2"
        data-max-width=&#39;720&#39;>
    <div>Another Breakpoint</div>
</div>

<div class="breakpoint"
        id="bp_3"
        data-max-width=&#39;720&#39;>
    <div>Third Breakpoint</div>
</div>

<div class="breakpoint"
        id="bp_4"
        data-max-width=&#39;720&#39;>
    <div>Fourth Breakpoint</div>
</div>

<div>
    <h4>A footer!</h4>
</div>

原答案

DisplayTemplates 是您的朋友。如果您的部分将是相同的,您可以将相关信息放入 ViewModel,然后将 List&lt;ViewModel&gt; 传递给 DisplayTemplate。然后,MVC 引擎将使用您的 ViewModel 的 DisplayTemplate 来为每个部分填写所需的代码。

您只需为 ViewModel 编写一次 DisplayTemplate 代码。

目前我没有任何示例代码,但如果您需要进一步的帮助,请对此发表评论,我会在周末整理出一些。

【讨论】:

  • 如果你有时间,请发布一个你的意思的例子,我还是有点迷茫。
  • 我进行了更多的挖掘,并在显示模板之上发现了编辑器模板。我有一个让它与我现在正在尝试实现的编辑器模板一起工作的理论。当您说显示时,您是指编辑器吗?
  • 抱歉,我还没有时间编写示例。有 EditorTemplates 和 DisplayTemplates。它们的工作方式大致相同,但通常您会在 DisplayTemplates 中使用 @Html.DisplayFor,在 EditorTemplates 中使用 @Html.EditorFor。明天我应该可以为您解决一些问题,然后我会编辑我的答案。
  • 如果我理解正确,要填充正文的 html 内容,我必须在控制器或某些服务中而不是视图中完成?
  • 这取决于您要做什么以及内容是什么。
猜你喜欢
  • 2017-01-25
  • 2016-05-07
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
相关资源
最近更新 更多