ZF2-如何在现有的控制器中添加一个新的窗体


ZF2 - How to add a new Form in an existing Controller?

我有一个带有筛选器LoginFilter.php的登录表单LoginForm.php,它有一个视图/login/index.phtml、一个控制器LoginController.php、两个工厂LoginControllerFactory.php&CCD_ 6,在CCD_。表单正确显示。

我有一个ViewController.php,它有一个方法idAction,它通过主页上名为/view/id.phtml的参数传递的id来显示帖子。我想在此视图中显示我创建的表单,但我不知道如何显示。首先,我创建了与创建登录表单完全相同的表单,但我意识到我已经在view路由内配置了id子路由,并在module.config.php中配置了Factory。

然后,我尝试在idAction方法中设置表单,就像在LoginController.php控制器中的indexAction中一样,但我收到了以下错误:An exception was raised while creating "Rxe'Factory'ViewController"; no instance returned

我现在将向您展示我尝试显示此新表单时所做的操作。

首先,表单本身:

class CommentForm extends Form
{
    public function buildForm()
    {
        $this->setAttribute('method', 'POST');
        $this->setAttribute('id', 'add-comment-form');
        $this->add(array(
            'name' => 'comment',
            'type' => 'textarea',
            'options' => array(
                'label' => 'Category'
            ),
            'attributes' => array(
                'class' => 'form-control'
            )
        ));
        $this->add(array(
            'name' => 'submit',
            'type' => 'submit',
            'attributes' => array(
                'class' => 'btn btn-success',
                'value' => 'Comment'
            )
        ));
    }
}

Form的CommentFormFactory.php调用其Filter并构建Form:

class CommentFormFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $form = new CommentForm();
        $form->setInputFilter($serviceLocator->get('Rxe'Factory'CommentFilter'));
        $form->buildForm();
        return $form;
    }
}

ViewControllerFactory.php调用CommentFormFactory.php,就像在LoginControllerFactory.php:中一样

class ViewControllerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $serviceManager = $serviceLocator->getServiceLocator();
        $viewController = new ViewController();
        $viewController->setPostsTable($serviceManager->get('Rxe'Factory'PostsTable'));
        $viewController->setCommentsTable($serviceManager->get('Rxe'Factory'CommentsTable'));
        $viewController->setCommentForm($serviceManager->get('Rxe'Factory'CommentForm'));
        return $viewController;
    }
}

ViewController.php,在其idActionViewModel:中调用表单

class ViewController extends AbstractActionController
{
    use PostsTableTrait;
    use CommentsTableTrait;
    private $commentForm;
    function setCommentForm($commentForm)
    {
        $this->commentForm = $commentForm;
    }
    public function indexAction()
    {
        $category = $this->params()->fromRoute('category');
        return new ViewModel(array(
            'posts' => $this->postsTable->getPostsByCategory($category),
            'categories' => $category
        ));
    }
    public function idAction()
    {
        $id = $this->params()->fromRoute('id');
        $viewModel = new ViewModel(array(
            'commentForm' => $this->commentForm,
            'commentParams' => $this->params()->fromPost(),
            'messages' => $this->flashMessenger()->getMessages(),
            'posts' => $this->postsTable->getPostById($id),
            'posts' => $this->commentsTable->getNumberOfCommentsByPost($id),
            'comments' => $this->commentsTable->getCommentsByPost($id)
        ));
        $viewModel->setTemplate('rxe/view/id.phtml');
        if ($this->getRequest()->isPost()) {
            $this->commentForm->setData($this->params()->fromPost());
            if ($this->commentForm->isValid()) {
                $this->flashMessenger()->addMessage('Thank you for your comment. :)');
            } else {
                $this->flashMessenger()->addMessage('Your comment wasn''t sent.');
            }
        }
        return $viewModel;
    }
}

最后是我的module.config.php

'controllers' => array(
    'invokables' => array(
        'Rxe'Controller'Index' => 'Rxe'Controller'IndexController',
        'Rxe'Controller'View' => 'Rxe'Controller'ViewController',
        'Rxe'Controller'Login' => 'Rxe'Controller'LoginController'
    ),
    'factories' => array(
        'Rxe'Factory'LoginController' => 'Rxe'Factory'LoginControllerFactory',
        'Rxe'Factory'ViewController' => 'Rxe'Factory'ViewControllerFactory',
        'Rxe'Factory'IndexController' => 'Rxe'Factory'IndexControllerFactory'
    )
),
'service_manager' => array(
    'factories' => array(
        'Rxe'Factory'LoginForm' => 'Rxe'Factory'LoginFormFactory',
        'Rxe'Factory'LoginFilter' => 'Rxe'Factory'LoginFilterFactory',
        'Rxe'Factory'CommentForm' => 'Rxe'Factory'CommentFormFactory',
        'Rxe'Factory'CommentFilter' => 'Rxe'Factory'CommentFilterFactory',
        'Rxe'Factory'PostsTable' => 'Rxe'Factory'PostsTableFactory',
        'Rxe'Factory'CategoriesTable' => 'Rxe'Factory'CategoriesTableFactory',
        'Rxe'Factory'CommentsTable' => 'Rxe'Factory'CommentsTableFactory',
        'Zend'Db'Adapter'AdapterService' => 'Zend'Db'Adapter'AdapterServiceFactory'
    )
),

如果你需要我给你看更多的代码,请告诉我。提前谢谢。

编辑#1

如果我删除ViewControllerFactory.php中调用Form的行,我会得到以下错误:Fatal error: Call to a member function prepare() on a non-object in /home/vol12_3/byethost4.com/b4_16354889/htdocs/module/Rxe/view/rxe/view/id.phtml on line 31

id.phtml是:

<!-- Comment form -->
<div id="comment-form-area" class="col-xs-3">
    <?php $this->commentForm->prepare() ?>
    <?php echo $this->form()->openTag($this->commentForm); ?>
    <div class="form-group comment-area">
        <?php echo $this->formRow($this->commentForm->get('comment_content')); ?>
    </div>
    <div class="form-group">
        <?php echo $this->formRow($this->commentForm->get('submit')); ?>
    </div>
    <?php echo $this->form()->closeTag(); ?>
</div>
<!-- /Comment form -->

尝试删除这些行

'invokables' => array(
    'Rxe'Controller'Index' => 'Rxe'Controller'IndexController',
    'Rxe'Controller'View' => 'Rxe'Controller'ViewController',
    'Rxe'Controller'Login' => 'Rxe'Controller'LoginController'
),

如果它不起作用,看看本教程如何创建正确的控制器工厂和传递依赖关系。https://samsonasik.wordpress.com/2015/03/31/zend-framework-2-using-__invokepluginmanager-manager-in-services-factory/

我如何构建表单的示例:

namespace Admin'Form;
use Zend'Form'Form;
use Zend'InputFilter'InputFilterProviderInterface;
class ContentForm extends Form implements InputFilterProviderInterface
{
    public function __construct()
    {
        parent::__construct("content");
    }
    public function init()
    {
        $this->setAttribute('method', 'post');
        $this->add([
            'type' => 'Zend'Form'Element'Text',
            'name' => 'title',
            'attributes' => [
                'required'   => true,
                'size'        => 40,
                'id'         => "seo-caption",
                'placeholder' => 'Title',
            ],
            'options' => [
                'label' => 'Title',
            ],
        ]);
        $this->add([
            'type' => 'Zend'Form'Element'Text',
            'name' => 'text',
            'attributes' => [
                'class'   => 'ckeditor',
                'rows'        => 5,
                'cols'      => 80,
            ],
            'options' => [
                'label' => 'Text',
            ],
        ]);
    }
    public function getInputFilterSpecification()
    {
        return [
            [
                "name"=>"title",
                "required" => true,
                'filters' => [
                    ['name' => 'StripTags'],
                    ['name' => 'StringTrim'],
                ],
                'validators' => [
                    ['name' => 'NotEmpty'],
                    [
                        'name'    => 'StringLength',
                        'options' => [
                            'encoding' => 'UTF-8',
                            'min' => 1,
                            'max' => 200,
                        ],
                    ],
                ],
            ],
            [
                "name"=>"text",
                "required" => true,
                'filters' => [
                    ['name' => 'StripTags'],
                    ['name' => 'StringTrim'],
                ],
                'validators' => [
                    ['name' => 'NotEmpty'],
                    [
                        'name'    => 'StringLength',
                        'options' => [
                            'encoding' => 'UTF-8',
                            'min' => 1,
                        ],
                    ],
                ],
            ],
        ];
    }
}

比我创建一个工厂命名空间Admin''Factory''Controller;

use Admin'Controller'ContentController;
use Zend'Mvc'Controller'ControllerManager;
class ContentFormFactory
{
    /**
     * @{inheritDoc}
     */
    public function __invoke(ControllerManager $controllerManager)
    {
        return new ContentController(
            $controllerManager->getServiceLocator()->get('FormElementManager')->get('Admin'Form'ContentForm')
        );
    }
}

在module.config.php内部,我有这个代码

'controllers' => [
    'factories' => [
        'Admin'Controller'Content' => "Admin'Factory'Controller'ContentFormFactory",
    ],
    'invokables' => [
        ...
    ],
],

请再给我们看一些代码。