2013-03-13 77 views
1

我創建了一個名爲AbstractApplicationForm的抽象表單類。我想服務定位器注入到它通過Zend\ServiceManager\ServiceLocatorAwareInterface能夠訪問譯者:注入ServiceLocator並將其用於抽象的Zend Form基類

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 ::得到無法獲取或創建翻譯實例

我沒有任何其他定義在Module.phpmodule.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'); 

所以譯者配置實際上是正確的,但我無法找回它以我的形式。 有人知道我在做什麼錯嗎?

回答

9

這實際上是同一個問題,你可以在ZF2 when to use getServiceLocator() and when not to

看到的FormElementManagerAbstractPluginManager,並在AbstractPluginManager構造函數中,添加以下service initializer

$this->addInitializer(function ($instance) use ($self) { 
    if ($instance instanceof ServiceLocatorAwareInterface) { 
     $instance->setServiceLocator($self); 
    } 
}); 

事實是,在這種情況下,$self是指插件管理器本身。這意味着任何實現Zend\ServiceManager\ServiceLocatorAwareInterface並由插件管理器產生的服務(在這種情況下爲FormElementManager)會獲得插件管理器本身的注入。

插件管理器不是主要的服務定位器(請參閱ZF2 when to use getServiceLocator() and when not to)。

Zend\Form\FormElementManager例如由主要服務經理制,當你叫:

$formElementManager = $this->serviceLocator->get('FormElementManager'); 

由於Zend\Form\FormElementManager實現Zend\ServiceManager\ServiceLocatorAwareInterface,它有實際的「主」服務管理器的引用。

因此,在您的形式:

$formElementManager = $this->getServiceLocator(); 

$mainServiceManager = $formElementManager->getServiceLocator(); 

$translator = $mainServiceManager->get('translator'); 
+0

謝謝你的解釋。現在完美。 – PWansch 2013-03-13 02:28:18

+0

這似乎不適用於字段集,如何在那裏使用翻譯器? – Aise 2016-01-31 18:14:28

1

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

我不明白你爲什麼有時要做到這一點,但它的作品。

+0

這可能是因爲http://stackoverflow.com/questions/14911965/zf2的 - 當使用getservicelocator和什麼時候不到/ 14915156#14915156 - 表單元素管理器實際上是一個不同的主服務器的服務管理器 – Ocramius 2013-03-13 01:44:26

+0

不錯。很高興知道。 – 2013-03-13 02:08:21

+0

謝謝你們的回答和解釋。那樣做了! – PWansch 2013-03-13 02:16:13

1

我有一個抽象類字段集和具體字段集類相同的結構。轉換器的注入方式完全相同,但是當我嘗試在字段集中「$ 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', 
     ), 
    ), 
), 

在我的意見譯者運行完美。 所以在momemnt我不知道,接下來要嘗試什麼。你能告訴我你是如何將翻譯服務添加到你的應用程序的?

編輯------------------------- 附加信息: 在字段集類

$this->getServiceLocator(); 

get'我是一個「Zend \ Form \ FormElementManager」類型的對象。這對於表單元素是正確的。

$this->getServiceLocator()->getServiceLocator(); 

但是這給了我NULL,而不是服務定位,對象...

感謝, 邁克爾