【问题标题】:MVC: Should "Display Color" logic be in the View or the Model?MVC:“显示颜色”逻辑应该在视图还是模型中?
【发布时间】:2012-02-08 11:50:04
【问题描述】:

我正在使用 CodeIgniter 编写票务管理系统,但我有一个 MVC 困境,条件着色应该放在模型中还是视图中? 该视图应在网格中显示所有工单。 假设门票有截止日期时间。剩下不到一小时时,车票应涂成红色,剩余一到六个小时时,车票应涂上黄色,剩余六小时以上时,车票应涂上颜色绿色。

那么,视图是否应该包含像

这样的逻辑
foreach($tickets as $ticket):
if($hours_left >= 6): <span class="green">...</span>
else if($hours_left >= 1 and $hours_left < 6) <span class="yellow">...</span>
if($hours_left < 1): <span class="red">...</span>

还是应该将颜色作为属性从 模型 中检索?

foreach($tickets as $ticket):
<span class="<?php echo $ticket->color; ?>">...</span>

在第一种情况下,视图获得了逻辑,它不再“愚蠢”了。更糟糕的是,如果这需要在多个视图中应用,我需要重复难以维护的代码,例如如果我想添加“蓝色”颜色。

在第二种情况下,我需要在模型中嵌入显示逻辑,这也违反了 MVC 原则。

颜色逻辑应该放在哪里?

【问题讨论】:

    标签: php model-view-controller codeigniter


    【解决方案1】:

    我不会担心颜色。而是考虑一些商业意义并在您的模型中确定那个(或在适当的情况下进一步向下):

    时间

    时间 1 - 6 : 中间期限

    time > 6 : 截止日期-ok

    或者任何有意义的事情。然后将其用作您的课程,让您根据需要选择颜色和其他样式。

    【讨论】:

      【解决方案2】:

      在这种情况下,颜色是一个视图问题,很可能在 CSS 中更远。

      另一方面,工单的“状态”是型号信息。罚单从正常到严重到紧急有一个门槛。因此,将这些数据与票证一起提供:

      $ticket['status']='severe';
      

      $ticket['status']=$ticketStatusObject
      

      取决于工单状态是否也是一个对象。

      最后,模型进入视图,您可以在那里应用逻辑。使其语义化,例如:

      <div class="ticket severe">
      

      <div class="ticket" status="severe">
      

      当然,你可以在 CSS 中格式化它。

      现在这里有一个有趣的概念,这对 MVC 来说是困难的。颜色就是视图,这基本上是正确的。但这也可能是出于商业目的。就像路灯变绿-橙-红。在这种情况下,我会从模型(TicketStatusObject)加载颜色。您仍然可以将它们放在 CSS 中,但根据模型生成 CSS,因为它会影响业务。

      如果您创建另一个视图层,例如移动应用程序,它将使用相同的模型并显示相同的颜色,因为这对您的应用程序和业务很重要。

      【讨论】:

        【解决方案3】:

        更新:添加了帮助代码示例

        我会编写一个辅助函数,您可以在视图中调用它来添加正确的 CSS。

        这样您就不会弄乱模型结构,例如,如果您在数据库中有一个名为 ticket_expires 的字段,您仍然可以在需要时在其他地方使用此值。

        制作辅助函数;

        /application/helpers 中创建一个名为 *ticket_helper.php* 的文件 在这个文件中放一些类似的东西;

        <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
        
        /**
         * Add Style to Ticket
         * 
         * @param string $expire_timestamp
         *
         */
        if ( ! function_exists('set_ticket_colour')) {
            function set_ticket_colour($expire_timestamp) {
                // do you logic here.
        
                // if you want to access your ticket model then...
                $_ci =& get_instance();
                // if model isn't autoloaded
                $_ci->load->model('ticket_model');
                $some_result = $_ci->ticket_model->some_function($some_param);
                return $some_result;
            }
        }
        

        请记住在需要时加载此帮助程序,或者自动加载它。

        所以在你看来;

        <?php echo set_ticket_colour($ticket->expires_time); ?>
        

        【讨论】:

        • 是否可以将该助手编写为 Ticket_model 的方法?例如: $ticket->get_color() ?这在 CI 中可能吗?
        【解决方案4】:

        我会将颜色用于模型中的显示逻辑(第二种方法)

        这并不真正违反 mvc 原则。

        您真正要做的是在模型中存储票的时间是否少于 6 小时或大于 6 小时。

        第二种方法还可以使您的模板更简洁,从视图中删除表示逻辑,这使图形设计师更容易理解视图。

        我不是 PHP 开发人员(因此无法提供代码),但我有一个帮助类,它提供了一个静态方法,该方法接受票证对象从中提取 hours_left 并将颜色作为字符串返回。

        【讨论】:

          【解决方案5】:

          您应该始终努力使您的观点尽可能简洁。这意味着尽可能多地删除 PHP 并将其推送到控制器、模型甚至帮助器中。

          我建议您在帮助程序中评估每张工单的剩余小时数,并使用 switch 语句返回应应用于该工单的以空格分隔的类列表。

          那么在你看来,就这么简单:

          <? foreach($ticket as $t): ?>
          <div class="<?= $t['classes'];?>"><?= $t['name']; ?></div>
          <? endforeach; ?>
          

          然后使用 CSS 标记类。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-04-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多