programing

Zend Framework 2: Ajax 호출에 대한 레이아웃 자동 비활성화

lastmoon 2023. 8. 20. 12:29
반응형

Zend Framework 2: Ajax 호출에 대한 레이아웃 자동 비활성화

현재 컨트롤러 작업 중 하나에 대한 AJAX 요청이 전체 페이지 HTML을 반환합니다.

해당 작업에 대한 HTML(.phtml 내용)만 반환했으면 합니다.

다음 코드는 특정 작업에 대한 레이아웃을 수동으로 비활성화하여 문제를 제대로 해결하지 못합니다.

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

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);
    }
}

생각은?

실제로 가장 좋은 것은 다른 전략을 쓰는 것입니다.수락 헤더를 자동으로 감지하여 Json-Format을 자동으로 반환할 수 있는 Json Strategy가 있지만 전체 페이지에 대한 Ajax-Calls와 마찬가지로 전체 페이지를 받고 싶을 수 있으므로 자동으로 작업을 수행하지 않는 것이 좋습니다.당신이 언급한 위의 해결책이 빠른 방법일 것입니다.

전속력으로 달릴 때는 한 줄만 더 가면 됩니다.컨트롤러 내에서 항상 정규화된 View Model을 반환하는 것이 좋습니다.예:

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
    ));
}

제 생각에 문제는 당신이 전화를 한다는 것입니다.setTerminal()뷰 모델에서$e->getViewModel()작업이 아니라 레이아웃 렌더링을 담당합니다.새 뷰 모델을 생성해야 합니다. 호출setTerminal(true)그리고 그것을 돌려주세요.전용 Ajax 컨트롤러를 사용하므로 작업이 Ajax인지 여부를 확인할 필요가 없습니다.

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;
    }
}

그리고 아약스/응답으로.ptml 단순하게 다음과 같습니다.

<?= $this->response ?>

이것이 최선의 해결책입니다그걸 알아내려고 거의 이틀을 보냈어요.지금까지 인터넷에 올린 사람은 아무도 없는 것 같습니다.

public function onBootstrap(MvcEvent $e)
{
    $eventManager= $e->getApplication()->getEventManager();

    // The next two lines are from the Zend Skeleton Application found on git
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);

    // Hybrid view for ajax calls (disable layout for xmlHttpRequests)
    $eventManager->getSharedManager()->attach('Zend\Mvc\Controller\AbstractController', MvcEvent::EVENT_DISPATCH, function(MvcEvent $event){

        /**
         * @var Request $request
         */
        $request = $event->getRequest();
        $viewModel = $event->getResult();

        if($request->isXmlHttpRequest()) {
            $viewModel->setTerminal(true);
        }

        return $viewModel;
    }, -95);

}

그래도 아직 만족스럽지는 않습니다.나는 listener로 플러그인을 생성하고 부트스트랩 방식 대신 구성 파일을 통해 구성할 것입니다.하지만 다음 번에는 이것을 허용할 것입니다 =P

저는 이 질문에 답했고 비슷한 것 같습니다. - 디스패치 이벤트에서 View Model 변수에 액세스합니다.

이벤트 콜백을 에 첨부합니다.dispatch이벤트 트리거.이 이벤트가 트리거되면 다음을 호출하여 조치 방법의 결과를 얻을 수 있습니다.$e->getResult()View Model을 반환하는 작업의 경우 setTerminal() 수정을 수행할 수 있습니다.

aimfeld 솔루션은 저에게 적합하지만, 템플릿의 위치에 문제가 있는 경우 모듈을 지정해 보십시오.

 $this->viewModel->setTemplate('application/ajax/response');

가장 좋은 방법은 멋진 json을 반환하고 레이아웃&뷰를 비활성화하는 jsonModel을 사용하는 것입니다.

public function ajaxCallAction()
    {
        return new JsonModel(
            [
                'success' => true
            ]
        );
    }

저는 전에 이 문제를 가지고 있었고 여기 그것을 해결하기 위한 빠른 속임수가 있습니다.

에 빈 .module/YourModule/view/layout/empty.phtml

은 이 의 보기 .<?php echo $this->content; ?>

당신의 금지당에서.Module.php을 layout ajax request로 합니다. 레레설이정이로으아웃/Ajax 요비있음어해

namespace YourModule;
use Zend\Mvc\MvcEvent;

class Module {
    public function onBootstrap(MvcEvent $e) {
        $sharedEvents = $e->getApplication()->getEventManager()->getSharedManager();
        $sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
            if ($e->getRequest()->isXmlHttpRequest()) {
                $controller = $e->getTarget();
                $controller->layout('layout/empty');
            }
        });
    }
}
public function myAjaxAction() 
{
    ....
    // View - stuff that you returning usually in a case of non-ajax requests
    View->setTerminal(true);
    return View;
}

언급URL : https://stackoverflow.com/questions/13178632/zend-framework-2-auto-disable-layout-for-ajax-calls

반응형