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

Dan*_*ito 17 php ajax zend-framework2

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

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

以下代码通过手动禁用特定操作的布局很难解决问题:

    $viewModel = new ViewModel();
    $viewModel->setTerminal(true);
    return $viewModel;
Run Code Online (Sandbox Code Playgroud)

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

另外,我在我的应用程序Module.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);
    }
}
Run Code Online (Sandbox Code Playgroud)

思考?

Sam*_*Sam 8

事实上,最好的办法就是编写另一份战略.有一个JsonStrategy可以自动检测accept头以自动返回Json-Format,但是就像Ajax-Calls for fullpages一样,它不会自动执行任务,因为你可能想要获得一个完整的页面.您提到的上述解决方案将是快速的方法.

当全速前进时,你只需要一条额外的线路.始终从控制器中返回完全限定的ViewModel是最佳做法.喜欢:

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
    ));
}
Run Code Online (Sandbox Code Playgroud)


aim*_*eld 6

我认为问题在于你正在调用负责渲染布局而不是动作setTerminal()的视图模型.您必须创建一个新的视图模型,调用并返回它.我使用专用的ajax控制器,因此无需确定动作是否为ajax:$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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在ajax/response.phtml中只需以下内容:

<?= $this->response ?>
Run Code Online (Sandbox Code Playgroud)