2012-11-01 14 views
15

मेरे नियंत्रक कार्यों में से एक के लिए एक AJAX अनुरोध वर्तमान में पूर्ण पृष्ठ HTML देता है।ज़ेंड फ्रेमवर्क 2: AJAX कॉल के लिए स्वतः अक्षम लेआउट

मैं केवल उस विशेष कार्रवाई के लिए 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); 
    } 
} 

विचार?

उत्तर

7

वास्तव में सबसे अच्छी बात एक और रणनीति लिखना होगा। एक JsonStrategy है जो Json-Format को स्वचालित रूप से वापस करने के लिए स्वीकृति शीर्षलेख को स्वतः पहचान सकता है, लेकिन पूर्णपृष्ठों के लिए अजाक्स-कॉल के साथ, यह अच्छा है कि यह स्वचालित रूप से चीजें नहीं करता है, क्योंकि आप एक पूर्ण पृष्ठ प्राप्त करना चाहते हैं। ऊपर उल्लिखित समाधान का उल्लेख करने का त्वरित तरीका होगा।

पूर्ण गति के लिए जाने पर, आपके पास केवल एक अतिरिक्त पंक्ति होगी। अपने नियंत्रक के भीतर से पूरी तरह से योग्य व्यू मॉडल्स को हमेशा वापस करने का यह सबसे अच्छा अभ्यास है। जैसा:

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

धन्यवाद, सैम - मैंने ऐप के Module.php के साथ एक दृष्टिकोण शामिल करने के लिए अपनी पोस्ट भी अपडेट की है। SetTerminal() को ViewModel पर कोई प्रभाव नहीं पड़ने पर कोई विचार क्यों है? –

+0

मेरा अनुमान है कि ऑनबूटस्ट्रैप नो व्यू मॉडेल() अभी तक मौजूद नहीं है, एक विचार नियंत्रक में टर्मिनल (सत्य) के साथ मॉडल को इंजेक्ट करना होगा और आउटपुट के लिए इसका उपयोग करना होगा (क्या मैं कोई समझ कर रहा हूं?) – Sam

0

मैं इस सवाल का जवाब दिया है और यह शायद लगता है इसी तरह - Access ViewModel variables on dispatch event

dispatch घटना ट्रिगर करने के लिए एक घटना कॉलबैक देते हैं। एक बार यह ईवेंट ट्रिगर हो जाने पर आपको $e->getResult() पर कॉल करके क्रिया विधि का परिणाम प्राप्त करने की अनुमति देनी चाहिए। एक ViewModel लौटने वाली कार्रवाई के मामले में आपको सेट टर्मिनल() संशोधन करने की अनुमति देनी चाहिए।

6

मुझे लगता है कि समस्या यह है कि आप को देखने के मॉडल $e->getViewModel() कि लेआउट, नहीं कार्रवाई प्रतिपादन के लिए जिम्मेदार है पर setTerminal() कॉल कर रहे है। आपको एक नया दृश्य मॉडल बनाना होगा, 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; 
    } 
} 

और ajax/response.phtml में बस निम्नलिखित:

<?= $this->response ?> 
0

aimfeld समाधान मेरे लिए काम करता

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

यहाँ सबसे अच्छा समाधान (मेरी विनम्र राय में) है:, लेकिन मामले में आप में से कुछ टेम्पलेट के स्थान के साथ मुद्दों प्रयोग, मॉड्यूल निर्दिष्ट करने के लिए प्रयास करें। मैंने इसे समझने के लिए लगभग दो दिन बिताए हैं। अब तक इंटरनेट पर किसी ने पोस्ट नहीं किया है।

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

} 

हालांकि मैं अभी भी संतुष्ट नहीं हूं। मैं एक श्रोता के रूप में एक प्लगइन बनाउंगा और इसे बूटस्ट्रैप विधि के बजाय कॉन्फ़िगरेशन फ़ाइल के माध्यम से कॉन्फ़िगर करता हूं।लेकिन मैं अगली बार = पी

+0

ध्यान रखें कि परिणाम एक नियंत्रक का 'व्यूमोडेल' बिल्कुल नहीं हो सकता है; यहां तक ​​कि अनुरोध 'ज़ेंड \ एचटीपी \ अनुरोध' भी नहीं हो सकता है, इसलिए जब आप ईवेंट श्रोताओं को लिखते हैं, तो सावधान रहें, हमेशा घटना से जो कुछ लेते हैं उस पर जगह नियंत्रण रखें, और याद रखें कि श्रोताओं को पूरे एमवीसी अनुप्रयोग चक्र को प्रभावित करता है, न केवल आपके मॉड्यूल। –

+0

मैं अपने नियंत्रक के अंदर इस विशिष्ट दृश्य मॉडल को कैसे एक्सेस करूं? – jkushner

-1
public function myAjaxAction() 
{ 
    .... 
    // View - stuff that you returning usually in a case of non-ajax requests 
    View->setTerminal(true); 
    return View; 
} 
0
सबसे अच्छा

JsonModel जो अच्छा json और आप के लिए अक्षम लेआउट & दृश्य देता है उपयोग करने के लिए है के लिए इस दूँगा।

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

यह अच्छा है जब आप वापस HTML भेजना चाहते हैं। – David

0

मुझे यह समस्या पहले और यहां हल करने के लिए एक quikc चाल है।

सबसे पहले, एक खाली लेआउट अपने लेआउट फ़ोल्डर में इस तरह <?php echo $this->content; ?>

अब बनाने module/YourModule/view/layout/empty.phtml

आप इस लेआउट में सामग्री देखने के केवल गूंज चाहिए अपने Module.php सेट लेआउट के लिए नियंत्रक लेआउट/खाली में 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'); 
      } 
     }); 
    } 
}