如何防止Controller中设置的变量从视图泄漏到元素中(隔离元素'变量范围)?

时间:2014-07-10 17:11:08

标签: cakephp

我设计了一个接受可选参数的Element。这是其中的一部分:

<?php if (!empty($title)): ?>
  <h2><?php echo $title; ?></h2>
<?php endif; ?>

我的问题是,如果控制器有一个如下定义的变量:

$this->set('title', 'Lorem ipsum');

标题会泄漏到元素中,设置不需要的标题吗?

我可以想到几个解决方法:

  1. 命名空间元素变量,例如: G。 $myElement_title代替$title

  2. 将所有变量放入嵌套数组中,例如: G:

    $this->element('myElement', array('data' => array( 'title' => 'Foo Bar' )));
    

    而不是

    $this->element('myElement', array( 'title' => 'Foo Bar' ));
    
  3. 这两种解决方案都令人讨厌。 :(

    PS我曾经尝试过EmberJS框架。它有两个类似于CakePHP的$this->element():子视图和组件的功能。子视图和组件之间的唯一区别是前者与父视图共享变量范围,后者具有隔离范围。当我读到这个,我想知道为什么差异。好吧,有了CakePHP我很难知道答案! :(

1 个答案:

答案 0 :(得分:0)

显然,CakePHP不提供这种功能。

这非常不幸,因为我需要两种元素:

  1. 查看部分内容。为了可维护性和可读性,我想将长大的视图分成几个文件。主视图文件包含HTML脚手架,而部分包含内容,合理组织到单独的文件中。变量范围应该是透明的。 E. g。主视图文件中定义的变量应该在元素中可用。我还想将这些文件保存在主视图文件所在文件夹的子文件夹中。

  2. 组件。这些是可重用的块,就像CakePHP元素的设计一样。但它们应该具有隔离范围:控制器中定义的变量不应泄漏到它们中。

  3. 不幸的是,CakePHP既没有提供。 CakePHP元素是这两个变体的组合,因此非常不方便:

    1. 元素是查看局部视图的不良解决方案,因为:

      • 主视图中定义的变量不会泄漏到元素中。
      • 元素文件不能与视图文件一起存储。
    2. 元素是组件的不良解决方案,因为:

      • 控制器中定义的变量会泄漏到元素中。
    3. 要解决后者,我正在使用这个助手:

      class MyAwesomeHelper extends AppHelper {
          public function el($element_name, $args = array()) {
              return $this->_View->element($element_name, array('args' => $args));
          } // el()
      }
      class HHelper extends MyAwesomeHelper {}
      

      它是$this->element()的包装器,它将所有参数作为单个$args参数传递给$this->element()

      使用示例:

      <?php echo $this->H->el('foo', array('bar' => 'baz', 'quux' => true)); ?>
      

      这与:

      相同
      <?php
        echo $this->element('foo', array(
          array('bar' => 'baz', 'quux' => true)
        ));
      ?>
      

      在元素内部,参数将作为$args数组的键进行访问:

      <?php if (!empty( $args['title'] )): ?>
        <h2><?php echo $args['title']; ?></h2>
      <?php endif; ?>
      

      如您所见,$args是元素参数的唯一访问点,此变量始终传递给元素。这意味着参数永远不会被控制器中定义的变量覆盖。