Cakephp 3 在应用程序控制器中设置的视图变量在呈现特定模板/AJAX 请求时不可用



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

之前的应用程序控制器过滤器

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

上述变量适用于所有 none 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']);
}

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

您可以尝试使用您的方法:

$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

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

$this->set('data');
$this->render('custom_view');

当你调用$this->set时,它会在控制器类上设置视图变量。这些变量最终将传递给视图生成器,后者创建一个新的 View 类,并返回包含此新视图的 HTML 的结果。

当您想手动渲染自己的视图时,您也需要手动向其传递视图变量 -$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 视图的最简单方法。虽然您通常可以继续在 beforeFilter 中使用$this->set,但您已经这样做了:

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变量中包含公司/地址/电子邮件。

例如,"view"函数可能如下所示:

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 AppViewAppView $this
*/
?>
{"response": <?= $this->fetch('content') ?> }

从文档中查看:

  • 启用数据视图https://book.cakephp.org/3/en/views/json-and-xml-views.html#enabling-data-views-in-your-application
  • 使用_serialize键https://book.cakephp.org/3/en/views/json-and-xml-views.html#using-data-views-with-the-serialize-key
  • 自定义布局https://book.cakephp.org/3/en/views.html#layouts

最新更新