1

という抽象フォーム クラスを作成しましたAbstractApplicationFormZend\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.phporには他に何も定義されていませんし、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');

したがって、トランスレータの設定は実際には正しいのですが、フォームで取得できません。誰かが私が間違っていることを知っていますか?

4

3 に答える 3

9

これは実際には、 getServiceLocator()を使用する場合と使用しない場合にZF2で見られるのと同じ問題です。

はでFormElementManagerありAbstractPluginManager、のコンストラクターにAbstractPluginManager次のサービス初期化子が追加されます。

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

事実は$self、このコンテキストでは、プラグインマネージャー自体を指します。Zend\ServiceManager\ServiceLocatorAwareInterfaceこれは、プラグインマネージャー(この場合はFormElementManager)によって生成され、プラグインマネージャー自体が注入されることを意味します。

プラグインマネージャーはメインのサービスロケーターではありません(ここでも、getServiceLocator()を使用する場合と使用しない場合はZF2を参照してください)。

インスタンスは、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-13T02:02:03.157 に答える
1

抽象フィールドセット クラスと具象フィールドセット クラスで同じ構造を持っています。Translator はまったく同じ方法で挿入されますが、フィールドセットで "$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',
        ),
    ),
),

私の見解では、翻訳者は完璧に機能します。現時点では、次に何を試すべきかわかりません。アプリケーションに翻訳サービスを追加した方法を教えていただけますか?

EDIT ------------------------- 追加情報: fieldset クラス内

$this->getServiceLocator();

「Zend\Form\FormElementManager」タイプのオブジェクトを取得してください。フォーム要素としては正しいです。

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

しかし、これにより ServiceLocator-Object の代わりに NULL が返されます...

ありがとう、マイケル

于 2013-04-06T09:17:46.217 に答える
1

あなたがしなければならないかもしれませんgetServiceLocator()->getServiceLocator()->get('translator')

時々これをしなければならない理由がわかりませんが、うまくいきます。

于 2013-03-13T01:24:48.807 に答える