为了保持我的脚本可维护,我将把每个脚本移动到他们自己的文件中,由控制器和操作组织:
// 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
这一切都很酷,但是我希望控制器自动添加这些,因为它显然知道控制器和动作的名称。
我觉得最好的地方是AppController::beforeRender()
。 (是?)
唯一的问题是我不知道如何将其实际添加到$scripts_for_layout
变量中。我认为获得对javascript
辅助对象的引用会起作用,但我无法从控制器中找到它!
class AppController extends Controller {
var $helpers = array("javascript", "html", "form");
function beforeRender() {
// ???
}
}
答案 0 :(得分: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>
答案 1 :(得分: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);
}
}
然后,在我们的控制器动作中,我们定义了这些数组:
$this->set('cssIncludes',array('special')); // this will link to /css/special.css
$this->set('jsIncludes',array('jquery')); // this will link to /js/jquery.js
对于需要在每个视图中加载的文件,我们只需将“静态”添加相同类型的链接到布局顶部,例如:
echo $javascript->link('global');
echo $html->css('global');
这对我们来说非常有效。祝你好运!
答案 2 :(得分:2)
有点新手,但在阅读之后,我的布局添加了以下内容:
if ($handle = opendir(WWW_ROOT . 'js' . DS . $this->params['controller'] . DS . $this->params['action']))
{
while (false !== ($entry = readdir($handle)))
{
$entry = str_replace(".js", "", $entry);
echo $this->Html->script($entry);
}
closedir($handle);
}
答案 3 :(得分:2)
我只需要进行特定于页面的包含,但我在documentation找到了一种更简洁的方法。您可以将其加载到default.ctp中的某个脚本块中。在相应的视图中,只需使用HTML帮助程序来推送脚本:
您可以使用块将脚本标记附加到特定块 选项:
echo $this->Html->script('wysiwyg', array('block' => 'scriptBottom'));
将<script type="text/javascript" href="/js/wysiwyg.js"></script>
添加到块中。
在您的布局中,您可以输出添加到的所有脚本标签 “scriptBottom”:
echo $this->fetch('scriptBottom');
答案 4 :(得分:1)
我能想到的最好方法是创建自己的custom AppView并让所有控制器都使用它:
class myController extends AppController {
var view = 'AppView';
...
}
然后,在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>');
}
但我先退一步思考一些事情,首先。
平均来说,你的脚本有多大?外部脚本调用的开销(在客户端缓存脚本之前)是否比向主输出流添加几百个字节更好(只需将脚本粘贴到页面中,内联)?
也许你会在中间的某个地方做得更好 - 通过控制器分割你的脚本,但不是动作。这样,在第一次访问任何操作后,客户端都拥有所有操作的所有脚本。这样,您可以避免为所有应用程序的脚本进行大量初始下载,但是您可以避免添加N个http往返(其中N是全新用户访问的操作数)。
解决问题的另一种方法是在javascript中完成所有操作。只是想出一个懒惰的加载方案。因此,您的应用程序只会加载一个非常小的loader.js,并且该脚本会确定要引入的其他JavaScript源。
注意:我从未测试过我的扩展视图黑客,但我敢打赌,如果你真的想这样做,它会起作用。
答案 5 :(得分:0)
在Convention over Configuration – what's the big deal?上有一个关于CakePHP博客文章的细节 - 它使用帮助器来指定Javascript文件:
<?php
class JsManagerHelper extends AppHelper {
var $helpers = array('Javascript');
//where's our jQuery path relevant to CakePHP's JS dir?
var $_jqueryPath = 'jquery';
//where do we keep our page/view relevant scripts?
var $_pageScriptPath = 'page_specific';
function myJs() {
return $this->Javascript->link($this->_jqueryPath . '/' .
$this->_pageScriptPath .'/' .
$this->params['controller'] . '_' .
$this->params['action'], false);
}
}
?>
然后你在视图中只有$jsManager->myJs();
。
答案 6 :(得分:0)
我为这个问题撰写了一个插件。
如果您有两个文件:
它会将add.js
包含在页面的脚本块中。
或强> 的
它会将/js/post/add.js包含在页面的脚本块中。
有一些可爱的功能,它就像豆子一样简单。您甚至可以在.js文件中使用PHP,并使用您在操作中设置的viewVars。最重要的是,您无需破解视图或布局文件即可使其工作,只需在布局中获取“脚本”块即可。您也可以简单地将.js写入另一个视图块。
您可以在此处查看:https://github.com/dizyart/cakephp-viewautoload
它处于早期阶段,所以请务必发表评论和心愿单!
答案 7 :(得分:0)
LI在 W1ckd 片段上工作了一点点(非常少),并且更容易为不同的操作共享相同的js:
if ( is_dir(WWW_ROOT . 'js' . DS . $this->params['controller'] ) && ( $handle = opendir( WWW_ROOT . 'js' . DS . $this->params['controller'] ) ) )
{
while ( false !== ( $entry = readdir( $handle ) ) )
{
if ( in_array( $this->params['action'], explode( '.', $entry ) ) ) {
$entry = str_replace( ".js", "", $entry );
echo $this->Html->script( $this->params['controller'].DS.$entry );
}
}
closedir( $handle );
}
这样你就可以拥有:
根目录/ JS /的控制器强> / view.edit.add.js
这个js将包含在这三个动作中(查看,编辑,添加)。
答案 8 :(得分:0)
使用Cake v3,你可以这样做。在特定控制器中添加所需的脚本。
//YourController.php
public function beforeRender (Event $event)
{
array_push($this->scripts, 'Admin/gallery');
parent::beforeRender($event);
}
在intialize中设置默认值并渲染一次 //AppController.php public function initialize() { 父::初始化();
$this->scripts = [];
}
public function beforeRender (Event $event)
{
/* Define scripts in beforeRender of Child */
$this->set('scripts', $this->scripts);
/*-----------------------------------------*/
}
现在你可以运行一次这个功能了。
<?= $this->Html->script($scripts) ?>