避免在CakePHP中为每个AJAX函数创建一个视图

3

我试图避免为我在控制器中使用的每个AJAX函数创建一个视图。(因为我不以任何方式操纵结果数据,在大多数情况下只是一个布尔值)

我在我的控制器中使用RequestHandler组件:

var $components = array('RequestHandler');

我在routes.php中添加了以下内容:

Router::parseExtensions('json');

我正在尝试让这个函数工作,但是我得到了一个“null”值:
public function test(){
    $this->layout = 'ajax';

    $result = '1';
    $this->set('_serialize', $result);
}

为了访问函数的json版本,我使用以.json结尾的URL,以避免加载任何视图。
http://localhost/cakephp/demoController/test.json

我一直在遵循CakePHP文档中的步骤: http://book.cakephp.org/2.0/en/views/json-and-xml-views.html#json-and-xml-views 我做错了什么?为什么我没有得到期望的结果,而是得到了null? 此外,如果我尝试序列化一些数组,像这样:
$result = array('demo' => '1');
$this->set('_serialize', $result);

我收到了这个通知: 注意 (8): 未定义索引: 1 [CORE\Cake\View\JsonView.php, line 89]Code Context                $data = array();                 foreach ($serialize as $key) {                     $data[$key] = $this->viewVars[$key];$view = null $layout = null $serialize = array( 'demo' => '1' ) $data = array() $key = '1'JsonView::render() - CORE\Cake\View\JsonView.php, line 89 Controller::render() - CORE\Cake\Controller\Controller.php, line 957 Dispatcher::_invoke() - CORE\Cake\Routing\Dispatcher.php, line 193 Dispatcher::dispatch() - CORE\Cake\Routing\Dispatcher.php, line 161 require - APP\webroot\index.php, line 92 [main] - ROOT\index.php, line 42{"1":null}
请注意,上述内容包含HTML标记,但不需要进行解释。
4个回答

4

据我了解,文档要求您指定一个视图变量,然后在使用_serialize键时引用该变量。这意味着您的代码片段应如下所示:

$result = '1';
$this->set('theResult', $result);
$this->set('_serialize', array('theResult'));

1
我在URL中没有.json扩展名,也没有在我的routes.php文件中添加Router::parseExtensions('json');行,所以@dhofstet's answer对我无效。
我的解决方案是添加renderAs()调用:
public $components = array('RequestHandler');

public function my_ajax_action() {
    // do something
    $result = '1';
    $this->set('result', $result);
    $this->set('_serialize', array('result'));
    $this->RequestHandler->renderAs($this, 'json');
}

-1
你可以创建一个元素并渲染它。
function test() {
    $this->autoRender = false;

    $result = array('demo' => '1');

    $this->set(compact('result'));
    $this->set('_serialize', array('result'));
    $this->render(DS.'Elements'.DS.'element_name');
}

查看文档


但是为每个函数创建一个元素几乎就像创建一个视图。这并不能解决我的问题。我想要的是减少“愚蠢”的视图数量。 - Alvaro
如果结果总是布尔值(或总是 $result),则可以为所有操作使用相同的元素。 - noslone
但是,如果我仍然需要处理某种视图,那么使用serialize方法的重点在哪里?难道这个方法不应该是为了避免使用视图吗?文档说:如果您不需要在将数据转换为json/xml之前进行任何自定义格式化,则可以跳过为控制器操作定义视图文件。 - Alvaro

-3

最简单的方法是这样的。对我来说效果很好。

public function fun() {
    $this->autoRender = false;
    $this->request->onlyAllow('ajax');

    $result = array('data1' => 'hello', 'data2' => 'world');

    return json_encode($result);
}

这是一个相当古老的问题,已经有了一个被接受的答案。如果你要发表一些东西,它真的应该包含一些解释的话语,或者一些文档链接之类的东西。一段随意的代码片段,没有任何评论,很可能对未来的读者或已经得到答案三年的OP没有什么用处。 - Chris Baker
之前的答案对我来说不起作用。我认为其他用户可能会遇到同样的问题。这就是为什么我添加了这段代码...因为它是最简单的方法。 - Devasish
太好了,但请解释一下。清晰表达没有任何惩罚,事实上恰恰相反。你添加的词语并没有增加任何内容——请解释一下自己的思路,为什么其他答案不起作用,为什么这个方法有效。你是如何得出这个答案的,使用的方法有哪些文档支持,哪些文档说明其他答案可能无效。这就是一个代码片段被踩的区别和一个优秀的晚回答之间的区别,后者因为更好而超越了被接受的答案。 - Chris Baker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接