首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在抽象Zend\Form基类中注入和使用ServiceLocator

在抽象Zend\Form基类中注入和使用ServiceLocator
EN

Stack Overflow用户
提问于 2013-03-12 16:39:55
回答 3查看 2.4K关注 0票数 1

我已经创建了一个名为AbstractApplicationForm的抽象表单类。我希望通过Zend\ServiceManager\ServiceLocatorAwareInterface将服务定位器注入到服务定位器中,以访问翻译程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
namespace Application\Form;

use Zend\Form\Form;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

abstract class AbstractApplicationForm 
    extends Form 
    implements ServiceLocatorAwareInterface
{
    protected $serviceLocator;
    protected $translator;

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

    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }       

    public function getTranslator()
    {
        if (!$this->translator) {
            $this->translator = $this->getServiceLocator()->get('translator');
        }

        return $this->translator;
    }
}

我的申请表将这个类扩展如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
namespace Trade\Form;

use Zend\Captcha;
use Zend\Captcha\Image;
use Zend\Form\Element;
use Application\Form\AbstractApplicationForm;

class MemberForm extends AbstractApplicationForm
{
    public function init()
    {
        $this->setAttribute('method', 'post');

        // Add the elements to the form
        $id = new Element\Hidden('id');
        $first_name = new Element\Text('first_name');
        $first_name->setLabel($this->getTranslator('First Name'))

通过这种方式,我可以使用getTranslator翻译标签。

到目前一切尚好。在我的控制器操作中,我创建如下形式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public function joinAction()
{
    // Create and initialize the member form for join
    $formManager = $this->serviceLocator->get('FormElementManager');
    $form        = $formManager->get('Trade\Form\MemberForm');

结果是一个ServiceManager异常:

Zend\ServiceManager\ServiceManager:get无法获取或创建翻译器实例

我没有在Module.phpmodule.config.php中定义任何其他东西,我也不认为我需要这样做。我在module.config.php中定义了如下的翻译程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
'translator' => array(
    'locale' => 'en_US',
    'translation_patterns' => array(
        array(
            'type'     => 'gettext',
            'base_dir' => __DIR__ . '/../language',
            'pattern'  => '%s.mo',
        ),
    ),

当我在控制器中得到它时,它工作得很好:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$sm               = $this->getServiceLocator();
$this->translator = $sm->get('translator');

因此,translator配置实际上是正确的,但我无法以我的形式检索它。有人知道我做错了什么吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-12 18:02:03

这实际上是你在ZF2何时使用getServiceLocator(),何时不使用可以看到的相同的问题

FormElementManager是一个AbstractPluginManager,在AbstractPluginManager的构造函数中,添加了以下服务初始化器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$this->addInitializer(function ($instance) use ($self) {
     if ($instance instanceof ServiceLocatorAwareInterface) {
        $instance->setServiceLocator($self);
    }
});

事实上,在这种情况下,$self指的是插件管理器本身。这意味着实现Zend\ServiceManager\ServiceLocatorAwareInterface并由插件管理器(在本例中是FormElementManager)生成的任何服务都会注入插件管理器本身。

插件管理器不是主要的服务定位器(同样,请参阅ZF2何时使用getServiceLocator(),何时不使用)。

Zend\Form\FormElementManager实例是由主服务管理器在调用时生成的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$formElementManager = $this->serviceLocator->get('FormElementManager');

由于Zend\Form\FormElementManager实现了Zend\ServiceManager\ServiceLocatorAwareInterface,所以它引用了实际的“主”服务管理器。

因此,以你的形式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$formElementManager = $this->getServiceLocator();

$mainServiceManager = $formElementManager->getServiceLocator();

$translator = $mainServiceManager->get('translator');
票数 9
EN

Stack Overflow用户

发布于 2013-03-12 17:24:48

你可能得做getServiceLocator()->getServiceLocator()->get('translator')

我不明白你为什么有时要这么做,但它有效。

票数 1
EN

Stack Overflow用户

发布于 2013-04-06 01:17:46

对于抽象的字段集类和具体的字段集类,我有相同的构造。翻译器的注入方式完全相同,但是当我在字段集中尝试"$this->getTranslator()“时,会引发以下异常:

Zend\ServiceManager\ServiceManager::get无法获取或创建翻译程序的实例。

因此SM无法找到翻译服务。我以以下方式添加(配置)了翻译程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
'service_manager' => array(
    'factories' => array(
        'translator' => 'Zend\I18n\Translator\TranslatorServiceFactory',
        'Navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory',
        'logger' => function ($sm) {
            $logger = new \Zend\Log\Logger();
            $config = $sm->get('Config');

            if ($config['logger']['writer'] == 'ChromePhp'):
                $logger->addWriter(new \Application\Log\Writer\ChromePhp()); else:
                $logger->addWriter('FirePhp');
            endif;
            return $logger;
        }
    ),
),
'translator' => array(
    'locale' => 'de_DE',
    'translation_file_patterns' => array(
        array(
            'type' => 'gettext',
            'base_dir' => __DIR__ . '/../language',
            'pattern' => '%s.mo',
        ),
    ),
),

在我看来,译者的作品是完美的。所以在妈妈那里,我不知道下一步该做什么。您能告诉我您是如何将翻译服务添加到应用程序中的吗?

编辑

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$this->getServiceLocator();

给我一个类型为"Zend\Form\FormElementManager“的对象。对于表单元素来说,这是正确的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$this->getServiceLocator()->getServiceLocator();

但这给了我NULL而不是ServiceLocator-对象.

谢谢你,迈克尔

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15374987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文