【问题标题】:ZF2 use view helper in Validator classZF2 在 Validator 类中使用视图助手
【发布时间】:2015-02-25 16:31:37
【问题描述】:

更新! ZF2、l10n 视图助手。我不明白如何在课堂上使用我的视图助手。 我想像这样使用它:$this->t('STRING TO TRANSLATE'); 下面的例子 注意!我只是在本地化项目,我不允许更改代码结构或类似的东西。而且我在 ZF2 中绝对是新手。 我的班级 -

class Project extends InputFilter{

据我了解,我必须实现 ServiceLocatorAwareInterface 接口,尝试过这个:

use Zend\ServiceManager\ServiceLocatorInterface as ServiceLocator;

class Project extends InputFilter implements ServiceLocator
{
    protected $services;

    public function __construct(Connection $p4, $mode, ServiceLocator $services)
    {
        $this->services = $services;

        //some code
        $this->add(...);

        $this->add(
            array(
                 'name'          => 'name',
                 'filters'       => array('trim'),
                 'validators'    => array(
                     array(
                         'name'      => 'NotEmpty',
                         'options'   => array(
                             'message'   =>  "Name is required and can't be empty."
                         )
                     ),
                     array(
                         'name'      => '\Application\Validator\Callback',
                         'options'   => array(
                             'callback'  => function ($value) use ($p4, $toId, $mode, $reserved) {
                                 $id = $toId($value);
                                 if (!$id) {
                                     return $this->t('STRING TO TRANSLATE');
                                 }

// more code here
                                 return true;
                             }
                         )
                     )
                 )
            )
        );         

        //some code
        $this->add(...);

     }    


    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
        $this->serviceLocator = $serviceLocator;
    }

    public function getServiceLocator() {
        return $this->serviceLocator;
    }
    //how to get this method work ???
    public function t($msg) {
        $translate = $this->services->get('ViewHelperManager')->get('t');
        return $translate($msg);
    }


}

在控制器中的使用:

use Projects\Filter\Project as ProjectFilter;

...

protected function doAddEdit($mode, $project = null)
{
    $p4Admin = $this->getServiceLocator()->get('p4_admin');
    $request = $this->getRequest();

    // process add request.
    if ($request->isPost()) {
        // pull out the data
        $data = $request->getPost();

        // configure our filter with the p4 connection and add/edit mode
        $filter = new ProjectFilter($p4Admin, $mode); // 
        $filter->setData($data);

        // if the data is valid, setup the project and save it
        $isValid = $filter->isValid();
        if ($isValid) {
            $values  = $filter->getValues();
            $project = new Project($p4Admin);
            $project->set($values)
                ->save();
        }

        return new JsonModel(
            array(
                'isValid'   => $isValid,
                'messages'  => $filter->getMessages(), // THESE array of messages i want to localize
                'redirect'  => '/projects/' . $filter->getValue('id')
            )
        );
    }

    // prepare view for form.
    $view = new ViewModel;
    $view->setVariables(
        array(
             'mode'     => $mode,
             'project'  => $project ?: new Project
        )
    );

    return $view;
}

我做错了什么?

【问题讨论】:

    标签: localization zend-framework2 view-helpers service-locator


    【解决方案1】:

    您在类构造函数中调用tr 方法。 tr 方法调用 $this->getServiceLocator()$this->getServiceLocator() 不会返回服务定位器实例,因为它只会在服务管理器创建实现ServiceLocatorAwareInterface 的对象后才被服务管理器注入。

    因此,您必须将服务定位器实例传递给构造函数,或者不要在 __construct 方法中依赖它。可能最简单的方法是将代码从构造函数移动到init 方法。只要您通过InputFilterManager 获取输入过滤器,Init 就会自动调用。

    另外,我认为您不需要 translator 视图助手。你应该可以像这样从服务管理器那里得到它:$serviceManager->get('translator')

    【讨论】:

    • 我已经更新了我的代码,请您检查一下有什么问题。也许我应该配置一些配置或者我的方法't'写不正确?
    • 你仍然依赖于构造方法。您需要手动将服务定位器传递给构造器——它不会自动注入。请将所有代码从 __construct 移至 init 方法,并告诉我这是否能解决您的问题。如果您在实际使用该输入类的位置显示代码,特别是您如何实例化/获取它,这也可能会有所帮助。
    • 我只是在本地化项目,所以我不允许将 __constructor() 更改为 init。无论如何,我尝试这样做: init(Connection $p4, $mode) - 没有结果。我也认为 ZF2 不支持 init 方法。我以为我已经手动传递了服务定位器作为参数,或者这不是你的意思?您能否展示如何手动将服务定位器实例传递给构造函数?它需要在 module.config.php 中进行一些配置吗?我将编辑主题以显示此验证器的用法。
    【解决方案2】:

    根本没有必要这样做,验证消息无论如何都会由验证器翻译。但是我认为你的配置有点错误

        $this->add(
            array(
                 'name'          => 'name',
                 'filters'       => array('trim'),)
                 'validators'    => array(
                     array(
                         'name'      => 'NotEmpty',
                         'options'   => array(
                             'messages' => array(
                                        \Zend\Validator\NotEmpty::IS_EMPTY => 'YOUR_TRANSLATION_STRING_IS_EMPTY',
                                        \Zend\Validator\NotEmpty::INVALID => 'YOUR_TRANSLATION_STRING_INVALID',
                              )
                         )
                 )
         ),
    

    阅读https://zf2-docs.readthedocs.org/en/latest/modules/zend.validator.html#translating-messages

    您需要确保正确管理您的依赖项才能使其正常工作,因此实际上取决于您如何使用输入过滤器。

    如果您不直接添加到表单或在模型上使用 InputFilterAwareInterface,则需要确保您的 InputFilter 已向 InputFilterPluginManager 注册,并且您使用 InputFilterPluginManager 检索它,而不是直接实例化

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多