-1

我在我的应用程序控制器中设置了一些视图变量,例如公司名称、地址、联系信息,这些变量会根据子域而变化,以便它们在所有视图模板中都可用。但是,我正在努力确定为什么在发出 ajax 请求时不可用。

//App Controller beforeFilter

$this->set('company', 'Test Company');
$this->set('address', '14 Test Street, Test, TE5 3ST');
$this->set('email', 'test@test.com');

上述变量可用于所有非 ajax,即当我不呈现特定模板请求时,但是对于下面的示例请求,我无法访问 test_data 模板中的这些变量。

function _ajaxGetTestData() 
{
    $view = new View();
    $content = $view->render('Home/Ajax/test_data');
    $response['content'] = $content;
    $response['success'] = TRUE;

    $this->set(compact('response'));
    $this->set('_serialize', ['response']);
}
4

3 回答 3

0

那是因为您没有从应用控制器序列化变量。

你可以试试你的方法:

$response['company'] = $company;
$response['address'] = $address;
$response['email'] = $email;

https://book.cakephp.org/3/en/views/json-and-xml-views.html#using-a-data-view-with-template-files

于 2019-12-06T09:28:47.323 回答
0

当您调用$this->set它时,它会在 Controller 类上设置视图变量。这些变量最终被传递给 View Builder,它创建一个新的 View 类并返回一个包含这个新 View 的 HTML 的 Result。

当您想手动呈现自己的视图时,您也需要手动将视图变量传递给它 -$this->set不是在您在此处创建的这个新视图类中设置视图变量:

$view = new View();
$content = $view->render('Home/Ajax/test_data'); // Has nothing to do with $this->set, you'd have to pass the variables in manually

这通常不是呈现 AJAX 视图的最简单方法。 虽然您通常可以像以前一样继续使用$this->setbeforeFilter :

public function beforeFilter(Event $event)
{
    $this->set('company', 'Test Company');
    $this->set('address', '14 Test Street, Test, TE5 3ST');
    $this->set('email', 'test@test.com');    
}

.. 使 AJAX 兼容的最简单方法是启用 JSON/XML 处理程序,让内置的 JSON/XML 渲染器发挥作用。

在操作函数(索引/视图/编辑/其他)中,只需在_serialize变量中包含公司/地址/电子邮件。

例如,“视图”函数可能如下所示:

public function view($id = null)
{
   // Do regular view stuff:
   $entity = $this->MyTable->get($id);
   $this->set('entity', $entity);

   // Include ALL the variables you want in the response in _serialize:
   $this->set('_serialize', ['entity', 'company','address', 'email']);
}

如果您确定需要自定义模板(不是必需的),请不要手动渲染,只需在检测到 AJAX 时设置模板即可:

if($this->request->is('ajax')){
    $this->viewBuilder()->setTemplate('Home/Ajax/test_data');
}

这将使用您设置的变量自动为您呈现$this->set

如果您想制作一个全局自定义模板(例如,使用“响应”节点包装所有数据),对于所有 AJAX 请求,请使用新布局而不是自定义模板:

if($this->request->is('ajax')){
    $this->viewBuilder()->setLayout('custom_json');
}

在src/Template/Layout/custom_json.ctp中创建此布局并根据需要对其进行格式化,例如:

<?php
/**
 * @var \App\View\AppView $this
 */
?>
{"response": <?= $this->fetch('content') ?> }

从文档中查看:

于 2019-12-09T22:40:35.843 回答
0

您必须在调用渲染之前设置视图变量。

$this->set('data');
$this->render('custom_view');
于 2019-12-08T08:29:21.270 回答