CakePHP:如何在控制器中使用视图元素


CakePHP: How to use a view element inside of a controller

我正试图找出如何使用我的视图元素中的一个控制器…

我知道,我知道:"不要那样做!"(99%的情况下这是正确答案)

但我想我其实有一个很好的理由。该操作正在处理返回标记的AJAX请求。返回的标记是一个列表,我使用元素在其他地方显示它。因此,为了保持我的代码DRY,我认为在这里这样做是合适的。

这可能吗?

Easy:

$view = new View($this, false);
$content = $view->element('my-element', $params);

:

不要再这样做了!!

有时,您需要从视图中呈现CakePhp元素,同时使用AJAX将其内容注入页面。在这种情况下,从控制器将元素呈现为常规视图比创建只包含<?php echo $this->element('some_element') ?>的专用视图要好,并且可以这样做:

<?php
public function ajax_action() {
    // set data used in the element
    $this->set('data', array('a'=>123, 'b'=>456, 'd'=>678));
    // disable layout template
    $this->layout = 'ajax';
    // render!
    $this->render('/Elements/some_element');
}

我知道这是一个老问题,其他人已经给出了基本相同的答案,但我想指出的是,这种方法(由Serge S.提供)…

<?php
public function ajax_action() {
    // set data used in the element
    $this->set('data', array('a'=>123, 'b'=>456, 'd'=>678));
    // disable layout template
    $this->layout = 'ajax';
    // render!
    $this->render('/Elements/some_element');
}

…并不是一种拙劣的解决方法,而是CakePHP文档中针对这种常见且合法的用例推荐的方法:

如果$view以'/'开头,则假定它是一个视图或元素文件相对于/app/View文件夹。这允许直接呈现

(再次感谢Serge S.提供上述代码)

$this->view = '/Elements/myelement';

您应该使用客户端模板。你应该永远不要从web服务或API返回标记,只返回数据。让你的JavaScript获取数据,然后按照你希望的方式格式化它。

例如:

function getItems() {
    $.get('/some/url', function(response) {
        if (response.data.length > 0) {
            for (var i = 0; i < response.data.length; i++) {
                var item = response.data[i];
                $('.results').append('<li>' + item.title + '</li>');
            }
        }
    });
};

这只是一个即兴写的例子。显然,您需要编写自己的实现。

我在Cake中做任何ajax处理的方式是有我自己的AjaxController。ajax类型的任何交互都在那里进行,它们反过来使用自己的视图(和视图部分/元素)。这样你就可以保持你的代码DRY,并隔离和传播所有的ajax用例。

摘录例子:

<?php
class AjaxController extends AppController {
    /**
    * (non-PHPdoc)
    * Everything going to this controller should be accessed by Ajax. End of story.
    * @see Controller::beforeFilter()
    */
    public function beforeFilter() {
        parent::beforeFilter();
        $this->autoRender = false;
        $this->layout = false;
        if (!$this->request->is('ajax')) {
            $this->redirect('/');
        }
    }
    public function preview() {
        if ($this->request->is('ajax')) {
            $this->set('data', $this->data);
            $this->render('/Elements/ajaxpreview');
        }
    } 
?>

来源:https://github.com/Sobient/dosspirit/blob/master/app/Controller/AjaxController.php