ZF3:如何从控制器中的另一个动作中获取一个动作的视图?
ZF3: How to get view of an action from another action in the controller?
在我的控制器动作中,我想抓取另一个动作的渲染整页:
class MycontrollerController extends AbstractActionController
{
public function firstactionAction()
{
$html = some_function_to_get_the_rendered_page_of_secondaction();
}
public function secondactionAction()
{
return new ViewModel();
}
}
谨慎使用setTemplate()
MycontrollerControllerFactory.php
<?php
namespace Application\Controller\Service;
use Application\Controller\MycontrollerController;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class MycontrollerControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$controller = new MycontrollerController();
$controller->setRenderer($container->get('Zend\View\Renderer\PhpRenderer'));
return $controller;
}
}
MycontrollerController.php
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class MycontrollerController extends AbstractActionController
{
/**
* @var \Zend\View\Renderer\PhpRenderer
*/
protected $renderer;
/**
* @return \Zend\View\Renderer\PhpRenderer
*/
public function getRenderer()
{
return $this->renderer;
}
/**
* @param \Zend\View\Renderer\PhpRenderer $renderer
* @return self
*/
public function setRenderer($renderer)
{
$this->renderer = $renderer;
return $this;
}
public function firstAction()
{
if ($this->yourMethod()) {
$secondView = $this->secondAction();
$html = $this->getRenderer()->render($secondView);
}
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/first');
return $view;
}
public function secondAction()
{
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/second');
return $view;
}
}
所以,我建议创建一个新插件 'htmlRender' :
module.config.php
'controller_plugins' => [
'factories' => [
'htmlRender' => Application\Mvc\Controller\Plugin\Service\HtmlRenderFactory::class,
],
],
HtmlRenderFactory.php
<?php
namespace Application\Mvc\Controller\Plugin\Service;
use Application\Mvc\Controller\Plugin\HtmlRender;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\View\Renderer\PhpRenderer;
class HtmlRenderFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$plugin = new HtmlRender();
$plugin->setRenderer($container->get(PhpRenderer::class));
return $plugin;
}
}
HtmlRender.php
<?php
namespace Application\Mvc\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
use Zend\View\Renderer\RendererInterface;
class HtmlRender extends AbstractPlugin
{
/**
* @var \Zend\View\Renderer\PhpRenderer
*/
protected $renderer;
/**
* @param string|\Zend\View\Model\ModelInterface $nameOrModel
* @param null|array|\Traversable $values
* @param string|bool|\Zend\View\Model\ModelInterface $layout
* @return string
*/
public function __invoke($nameOrModel, $values = null, $layout = false)
{
$content = $this->getRenderer()->render($nameOrModel, $values);
if (!$layout) {
return $content;
}
if (true === $layout) {
$layout = 'layout/layout';
}
return $this->getRenderer()->render($layout, [
'content' => $content,
]);
}
/**
* @return \Zend\View\Renderer\PhpRenderer
*/
public function getRenderer()
{
return $this->renderer;
}
/**
* @param \Zend\View\Renderer\PhpRenderer|RendererInterface $renderer
* @return self
*/
public function setRenderer(RendererInterface $renderer)
{
$this->renderer = $renderer;
return $this;
}
}
在MycontrollerController.php
中使用
<?php
class MycontrollerController extends AbstractActionController
{
public function firstAction()
{
if ($this->yourMethod()) {
// Option 1 without layout
$html = $this->htmlRender($secondView);
// Option 2 without layout
$html = $this->htmlRender('namespace/my-controller/second', $yourVariables));
// Option 1 with layout
$html = $this->htmlRender($secondView, null, true);
//$html = $this->htmlRender($secondView, null, 'layout/my-custom-layout');
// Option 2 with layout
$html = $this->htmlRender('namespace/my-controller/second', $yourVariables, true));
//$html = $this->htmlRender('namespace/my-controller/second', $yourVariables, 'layout/my-custom-layout');
}
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/first');
return $view;
}
public function secondAction()
{
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/second');
return $view;
}
}
在我的控制器动作中,我想抓取另一个动作的渲染整页:
class MycontrollerController extends AbstractActionController
{
public function firstactionAction()
{
$html = some_function_to_get_the_rendered_page_of_secondaction();
}
public function secondactionAction()
{
return new ViewModel();
}
}
谨慎使用setTemplate()
MycontrollerControllerFactory.php
<?php
namespace Application\Controller\Service;
use Application\Controller\MycontrollerController;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class MycontrollerControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$controller = new MycontrollerController();
$controller->setRenderer($container->get('Zend\View\Renderer\PhpRenderer'));
return $controller;
}
}
MycontrollerController.php
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class MycontrollerController extends AbstractActionController
{
/**
* @var \Zend\View\Renderer\PhpRenderer
*/
protected $renderer;
/**
* @return \Zend\View\Renderer\PhpRenderer
*/
public function getRenderer()
{
return $this->renderer;
}
/**
* @param \Zend\View\Renderer\PhpRenderer $renderer
* @return self
*/
public function setRenderer($renderer)
{
$this->renderer = $renderer;
return $this;
}
public function firstAction()
{
if ($this->yourMethod()) {
$secondView = $this->secondAction();
$html = $this->getRenderer()->render($secondView);
}
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/first');
return $view;
}
public function secondAction()
{
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/second');
return $view;
}
}
所以,我建议创建一个新插件 'htmlRender' :
module.config.php
'controller_plugins' => [
'factories' => [
'htmlRender' => Application\Mvc\Controller\Plugin\Service\HtmlRenderFactory::class,
],
],
HtmlRenderFactory.php
<?php
namespace Application\Mvc\Controller\Plugin\Service;
use Application\Mvc\Controller\Plugin\HtmlRender;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Zend\View\Renderer\PhpRenderer;
class HtmlRenderFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$plugin = new HtmlRender();
$plugin->setRenderer($container->get(PhpRenderer::class));
return $plugin;
}
}
HtmlRender.php
<?php
namespace Application\Mvc\Controller\Plugin;
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
use Zend\View\Renderer\RendererInterface;
class HtmlRender extends AbstractPlugin
{
/**
* @var \Zend\View\Renderer\PhpRenderer
*/
protected $renderer;
/**
* @param string|\Zend\View\Model\ModelInterface $nameOrModel
* @param null|array|\Traversable $values
* @param string|bool|\Zend\View\Model\ModelInterface $layout
* @return string
*/
public function __invoke($nameOrModel, $values = null, $layout = false)
{
$content = $this->getRenderer()->render($nameOrModel, $values);
if (!$layout) {
return $content;
}
if (true === $layout) {
$layout = 'layout/layout';
}
return $this->getRenderer()->render($layout, [
'content' => $content,
]);
}
/**
* @return \Zend\View\Renderer\PhpRenderer
*/
public function getRenderer()
{
return $this->renderer;
}
/**
* @param \Zend\View\Renderer\PhpRenderer|RendererInterface $renderer
* @return self
*/
public function setRenderer(RendererInterface $renderer)
{
$this->renderer = $renderer;
return $this;
}
}
在MycontrollerController.php
中使用<?php
class MycontrollerController extends AbstractActionController
{
public function firstAction()
{
if ($this->yourMethod()) {
// Option 1 without layout
$html = $this->htmlRender($secondView);
// Option 2 without layout
$html = $this->htmlRender('namespace/my-controller/second', $yourVariables));
// Option 1 with layout
$html = $this->htmlRender($secondView, null, true);
//$html = $this->htmlRender($secondView, null, 'layout/my-custom-layout');
// Option 2 with layout
$html = $this->htmlRender('namespace/my-controller/second', $yourVariables, true));
//$html = $this->htmlRender('namespace/my-controller/second', $yourVariables, 'layout/my-custom-layout');
}
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/first');
return $view;
}
public function secondAction()
{
$view = new ViewModel();
$view->setTemplate('namespace/my-controller/second');
return $view;
}
}