Zend Framework 2:自动禁用 ajax 调用的布局

2022-08-30 23:36:18

对我的控制器操作之一的 AJAX 请求当前返回整页 HTML。

我只希望它返回该特定操作的HTML(.phtml内容)。

以下代码通过手动禁用特定操作的布局来很好地解决了该问题:

    $viewModel = new ViewModel();
    $viewModel->setTerminal(true);
    return $viewModel;

如何使我的应用程序在检测到 AJAX 请求时自动禁用布局?我需要为此编写自定义策略吗?任何关于如何做到这一点的建议都非常感谢。

此外,我已经在我的应用程序模块中尝试了以下代码.php - 它正在正确检测AJAX,但setTerminal()没有禁用布局。

public function onBootstrap(EventInterface $e)
{
    $application = $e->getApplication();
    $application->getEventManager()->attach('route', array($this, 'setLayout'), 100);

    $this->setApplication($application);

    $this->initPhpSettings($e);
    $this->initSession($e);
    $this->initTranslator($e);
    $this->initAppDi($e);
}

public function setLayout(EventInterface $e)
{
    $request = $e->getRequest();
    $server  = $request->getServer();

    if ($request->isXmlHttpRequest()) {
        $view_model = $e->getViewModel();
        $view_model->setTerminal(true);
    }
}

思潮?


答案 1

事实上,最好的办法是写另一个策略。有一个JsonStrategy可以自动检测接受标头以自动返回Json-Format,但是与Ajax-Calls一样,它不会自动执行某些操作是件好事,因为您可能希望获得完整的页面。上面提到的解决方案是您提到的快速方法。

当全速行驶时,您只有一条额外的线路。最佳做法是始终从控制器中返回完全限定的 ViewModels。喜欢:

public function indexAction() 
{
    $request   = $this->getRequest();
    $viewModel = new ViewModel();
    $viewModel->setTemplate('module/controller/action');
    $viewModel->setTerminal($request->isXmlHttpRequest());

    return $viewModel->setVariables(array(
         //list of vars
    ));
}

答案 2

我认为问题在于,您调用的是负责呈现布局的视图模型,而不是操作。您必须创建一个新的视图模型,调用 ,然后将其返回。我使用专用的ajax控制器,因此无需确定操作是否是ajax:setTerminal()$e->getViewModel()setTerminal(true)

use Zend\View\Model\ViewModel;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Controller\AbstractActionController;

class AjaxController extends AbstractActionController
{
    protected $viewModel;

    public function onDispatch(MvcEvent $mvcEvent)
    {
        $this->viewModel = new ViewModel; // Don't use $mvcEvent->getViewModel()!
        $this->viewModel->setTemplate('ajax/response');
        $this->viewModel->setTerminal(true); // Layout won't be rendered

        return parent::onDispatch($mvcEvent);
    }

    public function someAjaxAction()
    {
        $this->viewModel->setVariable('response', 'success');

        return $this->viewModel;
    }
}

在 ajax/response.phtml 中,只需执行以下操作:

<?= $this->response ?>

推荐