【问题标题】:PHP MVC: Where to Put Dynamically Generated JavascriptPHP MVC:在哪里放置动态生成的 Javascript
【发布时间】:2011-01-03 21:40:27
【问题描述】:

大多数 PHP MVC 系统遵循这样一种模式,即请求被路由到特定的控制器操作,然后控制器设置一组变量以在视图中使用。

当您处于使用大量动态 HTML 作为 UI 元素的代理/服务工作环境中时,这种模式会导致生成大量带有视图变量的 javascript

<script type="text/javascript">
    jQuery(document).ready(function(){
        $('#ui-element).init(
            {
                'param1':<?=$this->param1;?>,
                'param2':<?=$this->param2;?>,                   
            }
        );
    });
</script>

虽然这可行,但我发现它会导致视图包含 HTML、PHP 和 Javascript 的可怕意大利面条混合。它还冒犯了某类前端开发人员,他们认为所有的 javascript 都应该包含在外部文件中。

那么,您处理这个问题的模式/实践是什么?具体来说,当您想为 PHP MVC 框架中的 Javascript 小部件提供一组默认数据时,您如何在保持干净和模块化的同时做到这一点?这只是纪律问题,还是是否有特定的设计模式可以强制模块化**,同时仍然为有才华的客户端开发人员提供以标记为中心的环境。

【问题讨论】:

    标签: php javascript model-view-controller views


    【解决方案1】:

    编辑: 好吧,您不必那么详细,您可以简单地拥有一个仅代理 ob_start/ob_get_clean 的 php 类/函数,然后将 js 存储在某处,然后将 js 输出到其他地方。不一定要通过php来支持或集成库的功能...

    如果可以像下面这样简单:

    class UnobtrusiveJsHelper {
      protected static $_instance;
      protected $_js = array();
      protected $_ready = array();
    
      public static function getInstance()
      {
      }
    
      public static function setInstance(UnobtrusiveJsHelper $instance)
      {
      }
    
      public function captureStart($key = null)
      {
        if(null !== $key)
        {
          $this->_js[$key] = null;
        }
        ob_start();
      }
    
      public function captureEnd($key = null)
      {
        if(null !== $key)
        {
          $this->_js[$key] = ob_get_clean();
          return;
        }
        $this->_js[] = ob_get_clean();
    
       public function __toString()
       {
          return $this->dumpJs() . $this->_dumpReady();
       }
    
       public function dumpJs(array $attributes = null)
       {
          if(!empty($this->_js))
          {
             return "<script type=\"text/javascript\">". implode("\n", $this->_js) . "</script>";
          }
    
          return null;
       }
    
       public function dumpReady(array $attributes = null)
       {
          if(!empty($this->_js))
          {
             return '<script type="text/javascript">$(document).ready(function(){'. implode("\n", $this->_js) . '});</script>';
          }
    
          return null;
       }
    
    }
    

    然后在您的控制器中:$js = UnobtrusiveJsHelper::getInstance();

    在你看来:

    <?php $js->captureStart(); ?>
      var myjsvariable = 0;
    <?php $js->captureEnd();
    

    在你的布局中(假设这里有两步视图): &lt;?php echo isset($js) ? $js : null ?&gt;


    这就是你使用助手的目的。例如在 Zend_Framework 中,所有这些小的onLoad/Ready sn-ps 都被添加到堆栈中。然后将它们全部输出到头部的一个位置。

    我有一个用于 jQ 的特殊助手,它在 Symfony 下也可以做类似的事情。

    这些允许像$jq-&gt;setVar('myjsvar', 1); 这样的东西,然后当我转储这个时,我得到类似的东西:

    var myjsvar = 1; 在头部的脚本标签中。

    查看 ZendX_Jquery 和 Zend_Dojo 以及它们各自的视图帮助器类,以获得功能的一个很好的示例。

    【讨论】:

    • 我个人喜欢这种方法,如果每个人都同意,那就太好了,但我发现它最终会阻碍有才华的客户端开发人员,因为 1. 他们的视图中有这些非本地 blob 2。当您想要合并一些新的 jQuery/Dojo/Third 方元素时,编写助手会产生前期成本。使用 PHP 生成 HTML/Javascript(这是助手所做的)似乎比纯基于视图的方法需要更多的开发时间。不过,有用的信息,非常感谢!
    【解决方案2】:

    很多讨论都是关于最佳实践的。老实说,如果

    <script src='/js/widgets.js'></script>
    
    <script type="text/javascript">
        jQuery(document).ready(function(){
             showSomeWidget(<?=$this->name ?> , <?=$this->place ?> );
        }
    </script>
    

    你也可以使用像 Dojo 这样的 jQuery 模板插件,但我经常发现麻烦多于它的价值。

    【讨论】:

      猜你喜欢
      • 2011-07-03
      • 1970-01-01
      • 2015-08-19
      • 2014-11-01
      • 2014-09-12
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      相关资源
      最近更新 更多