我正在寻找一种方法将 JavaScript 代码部分添加到我的插件所需的页面。我知道您可以通过
$this->addJs()
包含一个文件,但我需要根据插件设置模型中的设置动态构建 JavaScript。
我可以使用 default.htm 中的
{% put scripts %}...{% endput %}
块来执行此操作,但如果我在页面中多次使用该组件,则会多次注入。
有没有一种方法,无论组件在页面上使用多少次,都只需将代码注入到页面中一次?
弄清楚了这一点。在我的组件中,我添加了一个属性
$renderCount
并在 onRender()
方法中增加它。我需要做的就是检查组件默认模板中的 __SELF__.renderCount
并仅在它为 1 时输出脚本。
我在 Plugin.php 中的私有函数 (
mapSettings
) 的帮助下这样做,以根据我的需要重写设置。
Event::listen('cms.page.beforeRenderPage', function($controller, $page) {
if($page->hasComponent('myComponentName')) {
Event::listen('cms.page.render', function($controller, $pageContents) {
$this->settings = \Acme\Plugin\Models\Settings::instance();
$script = "<script>let hounddd = {". json_encode($this->mapSettings()) ."};</script>";
return $pageContents . $script;
});
}
});
我首先关心的是如何避免浏览器缓存某些必需页面的 javascript 数据。
也许存在更好的方法将“后端”编译数据注入到 October 的 {% scripts %} 标记中。
要在使用
{% put scripts %}...{% endput %}
和 {% put styles %}...{% endput %}
时删除多重注入,您可以通过在 Plugin.php 函数中处理输出样式和脚本来删除重复项:
public function boot()
{
Event::listen('cms.block.render', function ($name, $result) {
if ($name == 'styles' || $name == 'scripts') {
$array = preg_split('/\n/', $result);
$items = array_filter(array_unique(array_map('trim', $array)));
return join(PHP_EOL, $items);
}
});
}