ZF2,使用Vendor Module的Form类的最佳实践是什么?

时间:2012-01-09 04:18:54

标签: zend-framework2

如何将自定义样式应用于供应商模块的表单或将其嵌入到我自己的View脚本中? 更具体地说,我想使用EdpUser Module(https://github.com/EvanDotPro/EdpUser)提供的表格。

最简单的方法似乎是直接修改供应商的脚本。但显然这会与供应商未来的更新发生冲突。

另一种方法似乎是将Vendor的Controller复制到我自己的Module中,然后提供我自己的视图。但是,这会遇到与供应商未来更新不同步的类似问题。我必须小心命名空间。

也许我应该扩展供应商的控制器而不是复制它。这应该适用于命名空间,我应该能够很容易地访问我的控制器中的窗体。在使用我自己的视图脚本时。这是正确的方式还是有更好的方式?

由于

1 个答案:

答案 0 :(得分:36)

这不是修改模块目录中任何的推荐方法,尤其是那些放在/vendor/中的模块。这也是必须将配置模板复制到您自己的/config/autoload/目录的原因。

模块必须提供足够的扩展点,以使其足够灵活以供您使用。这些可能性包括以下选项:

更改路线

ZfcUser模块在/ user url下注册自己。例如,如果要将其更改为/ account,只需将其添加到配置中:

<?php
return array(
    'di' => array(
        'instance' => array(
            'Zend\Mvc\Router\RouteStack' => array(
                'parameters' => array(
                    'routes' => array(
                        'zfcuser' => array(
                            'options' => array(
                                'route' => '/account',
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
);

更改控制器

如果您不满意使用ZfcUser\Controller\UserController并且想要覆盖此控制器中的某些操作,则可以创建自定义控制器,例如MyUser\Controller\UserController。如果您扩展ZfcUser\Controller\UserController并提供此配置,则可以继续:

<?php
return array(
    'di' => array(
        'instance' => array(
            'Zend\Mvc\Router\RouteStack' => array(
                'parameters' => array(
                    'routes' => array(
                        'zfcuser' => array(
                            'options' => array(
                                'defaults' => array(
                                    'controller' => 'MyUser\Controller\UserController'
                                ),
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
);

您还可以使用DI别名覆盖DI配置中的zfcuser别名:

<?php
return array(
    'di' => array(
        'instance' => array(
            'alias' => array(
                'zfcuser' => 'MyUser\Controller\UserController'
            ),
        ),
    ),
);

修改表单实例

例如,ZfcUser模块触发多个事件以帮助其他模块挂钩到表单创建过程。 ZfcUser\Form\LoginZfcUser\Form\Register在设置所有表单元素后触发init事件。这使您有机会添加或删除元素。

use Zend\EventManager\StaticEventManager;

$events = StaticEventManager::getInstance();
$events->attach('ZfcUser\Form\Login', 'init', function ($e) {
  $form = $e->getTarget();
  $form->addElement('text', 'something-new');
});

我需要在这里发表两点评论:

  1. 每个模块都必须提供自己的触发器。这两个表单上的ZfcUser都有init,但这不是每个模块的给定。您必须查看文档或源代码以了解相关信息。
  2. Zend\EventManager目前正在进行重构,以便通过StaticEventManager实例替换单例SharedEventManager,该实例可以通过Zend\Di定位器进行实例化。您可以在this Pull Request
  3. 中观看此重构的进度

    更改视图或表单呈现

    根据this RFCZend\Form组件可能会发生变化。特别是对于渲染,装饰器将被移除,“只是”普通视图助手将呈现形式。有了这个,加上覆盖视图的可能性,只需使用另一个只有一些视图脚本的模块就可以很容易地改变动作的渲染。

    如果您创建自己的模块并提供此配置,则可以向模板路径堆栈添加新位置:

    <?php
    return array(
        'di' => array(
            'instance' => array(
                'Zend\View\Resolver\TemplatePathStack' => array(
                    'parameters' => array(
                        'paths' => array(
                            'myuser' => __DIR__ . '/../view',
                        ),
                    ),
                ),
            ),
        ),
    );
    

    现在,您可以在模块的view目录中创建视图脚本。如果您的模块名为“MyUser”并位于/modules/MyUser下,并且您想要覆盖来自/vendor/ZfcUser/view/zfcuser/login.phtml的ZfcUser的登录视图脚本,请在/modules/MyUser/view/zfcuser/login.phtml中创建您的视图脚本。