PHP MVC:在哪里放置动态生成的Javascript

时间:2010-01-11 19:38:08

标签: php javascript model-view-controller views

大多数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小部件提供一组默认数据时,你如何在保持干净和模块化的同时做到这一点?这只是一个纪律问题,还是是否存在可以强制模块化的特定设计模式,同时仍然为有才能的客户端开发人员提供了一个以标记为中心的环境。

2 个答案:

答案 0 :(得分:3)

修改: 好吧,你不必得到那么详细,要么你可以简单地拥有一个只需代理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();

并在您的布局中(在此处设置两步视图): <?php echo isset($js) ? $js : null ?>


这是你使用助手的方法。例如,在Zend_Framework中,所有这些小onLoad/Ready个片段都被添加到堆栈中。然后他们就会在头部的一个地方立刻输出。

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

这些允许$jq->setVar('myjsvar', 1);之类的东西,然后当我转储它时,我会得到类似的东西:

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

查看ZendX_Jquery和Zend_Dojo及其各自的视图助手类,以获得该功能的一个很好的例子。

答案 1 :(得分:0)

很多讨论都是关于最佳实践的。老实说,如果&lt; 100条线,恕我直言,你正在做的事情很好。一种不同的方法就是从视图中调用一个函数并将js作为单独的文件,如下所示(具有适当的默认值):

<script src='/js/widgets.js'></script>

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

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