0

我正在使用 CakePHP 3.9

我正在尝试在我的视图单元中设置 css / script 依赖块。

我希望它在我的布局头部中被提取,但它不起作用。如果我想让它工作,我必须在调用单元之前/之后在视图中设置 css 依赖项。

有没有办法在 View Cell 中设置 css 依赖项?

我的观点:

<?= $this->cell('Post::post_input'); ?>
....

我的视图单元格:

<?php echo $this->Html->css(['element/post-input'], ['block' => true]);  ?>
<div class="post-input">...</div>

我的布局:

<html>
<head>
...
    <?php
    echo $this->fetch('css');
    echo $this->fetch('script');
    ?>
...
</head>
<body>
    <?php echo $this->fetch('content'); ?>
</body>
</html>
4

2 回答 2

1

它不起作用,因为单元格是使用单独视图实例的封闭环境,因此您在其模板中定义的所有块都将驻留在其内部视图中。

从文档:

单元格模板具有一个独立的范围,与用于呈现当前控制器操作或其他单元格的模板和布局的视图实例不同。因此,他们不知道在操作的模板/布局中进行的任何帮助调用或块设置,反之亦然。

食谱 > 视图 > 查看单元 > 实现单元

如果您不想在使用单元格时手动添加 CSS 块,那么我建议您构建一个自定义助手,可以生成(甚至直接回显)单元格并添加块,沿着这行:

<?php
// in src/View/Helper/PostHelper.php

namespace App\View\Helper;

use Cake\View\Helper;

/**
 * @property \Cake\View\Helper\HtmlHelper $Html
 */
class PostHelper extends Helper
{
    protected $helpers = [
        'Html'
    ];

    protected $wasPostInputCssAdded = false;

    public function postInput()
    {
        if (!$this->wasPostInputCssAdded) {
            $this->wasPostInputCssAdded = true;

            $this->Html->css(['element/post-input'], ['block' => true]);
        }

        return $this->_View->cell('Post::post_input');
    }
}

然后以下将添加块并回显单元格:

<?= $this->Post->postInput() ?>

另请参阅Cookbook > Views > Helpers > 创建 Helpers

于 2021-01-23T14:34:23.310 回答
1

另一个不需要重写模板的选项是创建一个Cell使用类的自定义CellView类。然后,视图类将单元格内容包装在一个布局中,该布局可以显示块,就像您通常在 Cake 视图/布局模板中所期望的那样。

<?php
declare(strict_types=1);

namespace App\View;

use Cake\View\Cell as BaseCell;
use Cake\View\View;

class Cell extends BaseCell
{
    /**
     * @inheritDoc
     */
    public function createView(?string $viewClass = null): View
    {
        // use custom CellView to for Cells
        return parent::createView(CellView::class);
    }
}

然后是 CellView:

<?php
declare(strict_types=1);

namespace App\View;

class CellView extends AppView
{
    /**
     * @inheritDoc
     */
    public function render(?string $template = null, $layout = null): string
    {
        $cellContents = parent::render($template, $layout);

        // wrap cell contents in "cell" layout
        return $this->renderLayout($cellContents, 'cell');
    }
}

现在所有单元格都使用了一个布局,剩下的就是创建一个单元格专用的基本布局:

/templates/layout/cell.php (CakePHP 3: /src/Template/Layout/cell.ctp )

<?php
/**
 * @var CellView $this
 */

use App\View\CellView;

echo $this->fetch('styles');
echo $this->fetch('content');
echo $this->fetch('scripts');

在这个初步工作之后,所有App\View\Cell的 s 都将使用“单元格”布局。我发现从长远来看,如果您使用不同的块或postLink带有块的 s,这会更直观。

注意:此处的代码适用于 CakePHP 4,但您需要做的就是使其与 CakePHP 3 兼容,只需匹配方法签名即可

于 2021-06-23T14:50:23.377 回答