将特定于页面的Javascript添加到CakePHP中的每个视图

nic*_*ckf 12 javascript cakephp

为了保持我的脚本可维护,我将把每个脚本移动到他们自己的文件中,由控制器和操作组织:

// scripts which only apply to /views/posts/add.ctp
/app/webroot/js/page/posts/add.js

// scripts which only apply to /view/users/index.ctp
/app/webroot/js/page/users/index.js
Run Code Online (Sandbox Code Playgroud)

这一切都很酷,但我希望控制器自动添加这些,因为它显然知道控制器和动作的名称.

我想这是最好的地方AppController::beforeRender().(是?)

唯一的问题是我不知道如何将其实际添加到$scripts_for_layout变量中.我认为获得对javascript辅助对象的引用会起作用,但我无法从控制器中找到它!

class AppController extends Controller {
    var $helpers = array("javascript", "html", "form");

    function beforeRender() {
        // ???
    }
}
Run Code Online (Sandbox Code Playgroud)

dec*_*eze 28

default.ctp布局文件中很容易做到:

.css每个控制器和/或控制器/操作自动包含文件的示例(因为我有这个,很容易适应.js文件):

<head>
...
<?php
    if (is_file(WWW_ROOT . 'css' . DS . $this->params['controller'] . '.css')) {
        echo $html->css($this->params['controller']);
    }
    if (is_file(WWW_ROOT . 'css' . DS . $this->params['controller'] . DS . $this->params['action'] . '.css')) {
        echo $html->css($this->params['controller'] . '/' . $this->params['action']);
    }
?>
...
</head>
Run Code Online (Sandbox Code Playgroud)

  • +1清洁方法和理解.`APP.WEBROOT_DIR.DS`可以替换为`WWW_ROOT`常量. (3认同)

ink*_*dmn 15

就像deceze所说,我们使用布局来做,虽然我发现我们的解决方案更优雅:)

在default.ctp中:

if(isset($cssIncludes)){
    foreach($cssIncludes as $css){
        echo $html->css($css);
    }
}

if(isset($jsIncludes)){
    foreach($jsIncludes as $js){
        echo $javascript->link($js);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在我们的控制器操作中,我们定义了这些数组:

$this->set('cssIncludes',array('special')); // this will link to /css/special.css
$this->set('jsIncludes',array('jquery'));   // this will link to /js/jquery.js
Run Code Online (Sandbox Code Playgroud)

对于需要在每个视图中加载的文件,我们只需将"静态"添加相同类型的链接到布局顶部,例如:

echo $javascript->link('global');
echo $html->css('global');
Run Code Online (Sandbox Code Playgroud)

这对我们来说非常有效.祝好运!


tim*_*dev 1

我能想到的最好方法是创建您自己的自定义 AppView并让所有控制器使用它:

class myController extends AppController {
  var view = 'AppView';
  ...
}
Run Code Online (Sandbox Code Playgroud)

然后,在 AppView 中的某个位置,您需要执行以下操作:

function __construct(&$controller, $register){
  parent::__construct($controller,$register);
  $this->addScript('<script type="text/javascript" src="/path/to/js/' . $this->controller . '/' . $this->action . '.js"></script>');
}
Run Code Online (Sandbox Code Playgroud)

但我会先退一步思考一些事情。

您的脚本平均有多大?外部脚本调用的开销(在客户端缓存脚本之前)是否比向主输出流添加几百个字节(通过将脚本内联地粘贴到页面中)更好?

也许你最好选择中间的某个地方——按控制器而不是操作来分割你的脚本。这样,在第一次访问任何操作后,客户端就拥有所有操作的所有脚本。这样,您可以避免对所有应用程序脚本进行大量初始下载,但可以避免添加 N 个 http 往返(其中 N 是全新用户访问的操作数)。

解决这个问题的另一种方法是用 JavaScript 来完成这一切。只需找出一个延迟加载方案即可。因此,您的应用程序只需加载一个非常小的 loader.js,该脚本就会确定要引入哪些其他 javascript 源。

注意:我从未测试过我的扩展视图技巧,但我打赌如果你真的想这样做的话它会起作用。