我已经创建了一个名为AbstractApplicationForm
的抽象表单类。我希望通过Zend\ServiceManager\ServiceLocatorAwareInterface
将服务定位器注入到服务定位器中,以访问翻译程序:
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;
}
}
我的申请表将这个类扩展如下:
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翻译标签。
到目前一切尚好。在我的控制器操作中,我创建如下形式:
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.php
或module.config.php
中定义任何其他东西,我也不认为我需要这样做。我在module.config.php
中定义了如下的翻译程序:
'translator' => array(
'locale' => 'en_US',
'translation_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
当我在控制器中得到它时,它工作得很好:
$sm = $this->getServiceLocator();
$this->translator = $sm->get('translator');
因此,translator配置实际上是正确的,但我无法以我的形式检索它。有人知道我做错了什么吗?
发布于 2013-03-12 18:02:03
这实际上是你在ZF2何时使用getServiceLocator(),何时不使用可以看到的相同的问题
FormElementManager
是一个AbstractPluginManager
,在AbstractPluginManager
的构造函数中,添加了以下服务初始化器:
$this->addInitializer(function ($instance) use ($self) {
if ($instance instanceof ServiceLocatorAwareInterface) {
$instance->setServiceLocator($self);
}
});
事实上,在这种情况下,$self
指的是插件管理器本身。这意味着实现Zend\ServiceManager\ServiceLocatorAwareInterface
并由插件管理器(在本例中是FormElementManager
)生成的任何服务都会注入插件管理器本身。
插件管理器不是主要的服务定位器(同样,请参阅ZF2何时使用getServiceLocator(),何时不使用)。
Zend\Form\FormElementManager
实例是由主服务管理器在调用时生成的:
$formElementManager = $this->serviceLocator->get('FormElementManager');
由于Zend\Form\FormElementManager
实现了Zend\ServiceManager\ServiceLocatorAwareInterface
,所以它引用了实际的“主”服务管理器。
因此,以你的形式:
$formElementManager = $this->getServiceLocator();
$mainServiceManager = $formElementManager->getServiceLocator();
$translator = $mainServiceManager->get('translator');
发布于 2013-03-12 17:24:48
你可能得做getServiceLocator()->getServiceLocator()->get('translator')
我不明白你为什么有时要这么做,但它有效。
发布于 2013-04-06 01:17:46
对于抽象的字段集类和具体的字段集类,我有相同的构造。翻译器的注入方式完全相同,但是当我在字段集中尝试"$this->getTranslator()“时,会引发以下异常:
Zend\ServiceManager\ServiceManager::get无法获取或创建翻译程序的实例。
因此SM无法找到翻译服务。我以以下方式添加(配置)了翻译程序:
'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',
),
),
),
在我看来,译者的作品是完美的。所以在妈妈那里,我不知道下一步该做什么。您能告诉我您是如何将翻译服务添加到应用程序中的吗?
编辑
$this->getServiceLocator();
给我一个类型为"Zend\Form\FormElementManager“的对象。对于表单元素来说,这是正确的。
$this->getServiceLocator()->getServiceLocator();
但这给了我NULL而不是ServiceLocator-对象.
谢谢你,迈克尔
https://stackoverflow.com/questions/15374987
复制相似问题