MVC:我应该在哪里格式化数据?

Posted

技术标签:

【中文标题】MVC:我应该在哪里格式化数据?【英文标题】:MVC: Where should I format data? 【发布时间】:2011-04-12 03:28:41 【问题描述】:

我从模型(包含数据的数组)中获取数据,我需要以特定格式显示。我需要遍历数组,格式化数据然后显示它。我应该在哪里格式化数据以显示?在模型、控制器或视图中? 谢谢。

【问题讨论】:

如你所愿。但在控制器中更好。 @Alexander 不是控制者的责任。 @我正在控制器中这样做... 重复***.com/questions/3237195/mvc-where-to-format-numbers 您的控制器只负责处理来自 UI 的输入。它不应该包含任何其他逻辑。 【参考方案1】:

对数组进行迭代并在视图中显示数据。因此我也会在视图中进行格式化。如果格式化很复杂和/或需要大量代码,请将其放入辅助函数中。

例如:

查看:

<?php foreach($array as $item): ?>
    <p><?php echo format_function($item); ?></p>
<?php endforeach; ?>

助手:

function format_function($text)

    // Do some formatting here...
    return $formatted_text;

【讨论】:

不要用这样的废话污染你的视野。视图不负责格式化。尝试使用一个单独的层来负责将您的对象模型格式化/转换为视图友好的视图模型:) 就像 Stefanvds 在 .NET 中所说的那样,存在一个名为 AutoMapper 的对象到对象映射器,也许 php 中有一个等价物。 我不同意。我知道的每个 MVC 框架都对此提供了开箱即用的支持。如果不是这样的情况,那么我应该使用助手做什么?您的解决方案可能更“纯粹”,但在这种简单的情况下,我觉得添加另一层有点过头了。 拥有一个额外层的好处是你可以说,如果对象类型是日期时间,你总是使用特殊的日期格式化程序而不是重复调用你的 datetimeformat 辅助方法的视图。所以你不会违反 DRY 原则。 @Rookian,我不同意您关于视图不负责格式化的说法。我限定了视图不应处理任何应用程序逻辑的声明。 我把这个方法作为一个静态方法放在一个类中,例如formatUtils::format($string)【参考方案2】:

如果您的 viewdata 包含来自不同模型的数据,或者只有一个模型的一部分,您可以创建一个 ViewModel,然后您可以使用 Automapper 进行映射。

ViewModel 有几个优点。它们很容易使用,整理您的数据,可以增加安全性,...

【讨论】:

是否有链接到该模式的详细信息? @fabrik 对于其他用途,请参阅View model (disambiguation)。引用模式时有链接永远不会有坏处。 我以前没听说过。我现在就去读!谢谢。【参考方案3】:

您可以在 View 中执行此操作。而不是在模型中 在 View 中你可以做特定的操作(converting/conditions/)

【讨论】:

【参考方案4】:

如果您从事更大的项目,我建议您有一个额外的层或类来负责将您的对象(即域模型对象)转换为数据传输对象(视图模型对象)。

否则应用在视图中进行格式化的建议:)

转换可能涉及格式化字符串、小数(货币)、日期时间等。 也可以将对象图(看看我的示例)转换为平面 DTO。

控制器将负责调用映射算法。

因此,在视图中您不必遍历对象的引用。相反,您使用格式良好的平面视图模型。

您的视图不会混乱,看起来很干净。

在 .NET 世界中可以使用一种工具来完成这种转换工作。它被称为自动映射器。也许在 PHP 中有一个等价物。

这是一个例子

这是一个对象模型:

你可以把它转换成这个智能视图模型:

这种方法的优点:

关注点分离

干净的视图

没有代码重复,即在每个视图中格式化日期时间。 (不要重复!)

这种方法的缺点:

一开始很贵,所以很少有项目不能从这种方法中获利

【讨论】:

【参考方案5】:

Presentation != 数据格式。请考虑以下示例:

具有产品页面的国际商店,其中包含有关产品尺寸等的各种信息。由于商店的国际性质,该数据应针对访问商店的每个区域设置不同的格式。例如:在欧洲,测量值显示为公制值,而美国客户看到相同的数据格式为英制值。

重要的一点是,这种特定类型的数据不应该针对每种格式存储多次,尽管与价格有关的数据应该存储。这是因为产品价格确实因地区而异。另一方面,不同地区的测量和日期普遍相同。只是它们的显示方式和格式不同。信息应始终以尽可能少的冗余存储。

这种商店的视图部分(或任何基于 MVC 的应用程序,就此而言)不应该做任何其他事情,除了呈现数据并确定如何将这些数据呈现给用户。视图不应以任何方式更改数据本身。这就是为什么有关测量和时间的信息应该以 ISO 标准化格式 存储的原因,这使得将数据格式化为其他格式更加容易。例如,测量值应存储为度量值。在从数据库中检索数据集之后,每个区域设置的数据的实际格式化应该在模型中进行,最好使用静态可访问的 Helper 类型类,以获得最大的灵活性。数据格式化后返回给控制器,控制器再返回到当前视图。

这种处理数据格式的方式的另一个重要优点是,当您尝试通过无视图操作(即通过 AJAX 检索的 JSON 对象)获取数据集时,您的数据仍将正确格式化。以任何方式(通过“普通”html 模板或作为 JSON/XML 字符串)发送回客户端的数据不应有所不同;只有它呈现的方式。

【讨论】:

同意。 SoC 是关于责任的,通常在带有被动视图的表示架构中(如 MVP 变体、MVVM、MVPVM 等),格式化/数据准备责任不是视图的责任。它将是演示者/视图模型,例如,在更“MVP 风格”的 ASP.Net MVC 的情况下,控制器更好,一个 vm)。被动性增加了测试/重用,使业务逻辑无法呈现。最后一段提出了一个我没有想到的好观点,这也意味着“格式化”不一定意味着格式化以供查看。【参考方案6】:

在您的视图中执行它,因为它负责演示。

原因

不这样做模型是你可以使用相同的数据渲染不同的视图(否则你需要创建不同的数据集), 不在控制器中做是因为它不是控制器的责任

见MVC background reading

【讨论】:

以上是关于MVC:我应该在哪里格式化数据?的主要内容,如果未能解决你的问题,请参考以下文章

在 MVC 中,我在哪里放置数据库查询?

我应该在 Laravel MVC 中的哪里保存模型?

asp.net MVC 怎么把数据库中取出的 数据 转换成json格式给easyui datagrid 控件

我应该在哪里定义 ExtJS 4 MVC 中的全局函数?

Symfony 中公共数据存储的数组放置在哪里

在哪里可以找到 epuf 格式?