16

フォームからアダプタを取得する必要がありますが、それでも取得できませんでした。

私のコントローラーでは、次を使用してアダプターを回復できます。

// module/Users/src/Users/Controller/UsersController.php
public function getUsersTable ()
{
    if (! $this->usersTable) {
        $sm = $this->getServiceLocator();
        $this->usersTable = $sm->get('Users\Model\UsersTable');
    }
    return $this->usersTable;
}

私のモジュールではそうしました:

// module/Users/Module.php  
public function getServiceConfig()
{
    return array(
            'factories' => array(
                    'Users\Model\UsersTable' =>  function($sm) {
                        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                        $uTable     = new UsersTable($dbAdapter);
                        return $uTable;
                    },
                    //I need to get this to the list of groups
                    'Users\Model\GroupsTable' =>  function($sm) {
                        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                        $gTable     = new GroupsTable($dbAdapter);
                        return $gTable;
                    },
            ),
    );
}

誰かがグループフォームからテーブルにアダプタを取得する方法の例を教えてもらえますか?

私はフォームユーザーにこの例に従いました:http: //framework.zend.com/manual/2.0/en/modules/zend.form.collections.html

ここから編集...

多分私は質問をするのは間違っていると言いました。

私が本当にする必要があるのは、選択(ドロップダウン)にテーブルグループからの情報を入力することです。

したがって、ServiceLocatorAwareInterface(このリンクを参照)を実装することで、userFormクラス内のサービスを取得する必要があります。デフォルトでは、Zend Framework MVCは、ServiceManagerインスタンスに挿入するイニシャライザーを登録します。ServiceLocatorAwareInterface任意のクラスを実装します。

テーブルグループから値を取得した後、selectにデータを入力します。

問題は、私が試したすべての方法の中で、getServiceLocator()がこれを返すことです。

Call to a member function get() on a non-object in
D:\WEBSERVER\htdocs\Zend2Control\module\Users\src\Users\Form\UsersForm.php
on line 46

ユーザーフォームでこれを実行したかっただけです...

namespace Users\Form;

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

class UsersForm extends Form implements ServiceLocatorAwareInterface
{

    protected $serviceLocator;

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

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

    public function __construct ($name = null)
    {
        parent::__construct('users');

        $this->setAttribute('method', 'post');        

        $sm = $this->getServiceLocator();

        $groups = $sm->get('Users\Model\GroupsTable')->fetchAll(); // line 46       

        $select = new Element\Select('groups');

        $options = array();

        foreach ($groups as $group) {

            $options[$group->id] = $group->name;
        }

        $select->setValueOptions($options);

        $this->add($select);

        // and more elements here...
4

6 に答える 6

8

ZF < 2.1の場合、ここでの他のさまざまな回答は一般的に正しいです。

2.1 がリリースされると、フレームワークには非常に優れたソリューションが用意されています。これは多かれ少なかれ DrBeza のソリューションを形式化したものです。つまり、初期化子を使用し、すべての依存関係が初期化された後に呼び出される init() メソッドにフォーム ブートストラップを移動します。

私は開発ブランチで遊んでいますが、それは非常にうまく機能します。

于 2013-01-17T00:01:08.003 に答える
6

これは、私がその問題を回避するために使用した方法です。

最初に、フォームに ServiceLocatorInterface を実装させたいと考えています。

その後もサービスロケーターを手動で注入する必要があり、フォーム全体がコンストラクター内で生成されるため、コンストラクターを介して注入する必要があります (ただし、コンストラクターですべてを構築するのは理想的ではありません)。

Module.php

/**
 * Get the service Config
 * 
 * @return array 
 */
public function getServiceConfig()
{
    return array(
        'factories' => array(
            /**
             * Inject ServiceLocator into our Form
             */
            'MyModule\Form\MyForm' =>  function($sm) {
                $form = new \MyModule\Form\MyFormForm('formname', $sm);
                //$form->setServiceLocator($sm);

                // Alternativly you can inject the adapter/gateway directly
                // just add a setter on your form object...
                //$form->setAdapter($sm->get('Users\Model\GroupsTable')); 

                return $form;
            },
        ),
    );
}

コントローラー内で、次のようなフォームを取得します。

// Service locator now injected
$form = $this->getServiceLocator()->get('MyModule\Form\MyForm');

これで、フォーム内のフル サービス ロケータにアクセスして、次のような他のサービスを取得できます。

$groups = $this->getServiceLocator()->get('Users\Model\GroupsTable')->fetchAll();
于 2012-11-28T12:35:20.420 に答える
1

module.php で 2 つのサービスを作成します。アダプターをフォームにフィードする方法を参照してください。

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'db_adapter' =>  function($sm) {
                $config = $sm->get('Configuration');
                $dbAdapter = new \Zend\Db\Adapter\Adapter($config['db']);
                return $dbAdapter;
            },

            'my_amazing_form' => function ($sm) {
                return new \dir\Form\SomeForm($sm->get('db_adapter'));
            },

        ),
    );
}

フォーム コードでは、そのフィードを何にでも使用します。

namespace ....\Form;

use Zend\Form\Factory as FormFactory;
use Zend\Form\Form;

class SomeForm extends Form
{

    public function __construct($adapter, $name = null)
    {
        parent::__construct($name);
        $factory = new FormFactory();

        if (null === $name) {
            $this->setName('whatever');
        }

    }
}
于 2012-09-18T12:51:47.943 に答える
0

これは、私がその問題を回避するために使用した方法です。

まず、Module.php でサービスを作成します (先ほど行ったように):

// module/Users/Module.php  
public function getServiceConfig()
{
    return array(
            'factories' => array(
                    'Users\Model\UsersTable' =>  function($sm) {
                        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                        $uTable     = new UsersTable($dbAdapter);
                        return $uTable;
                    },
                    //I need to get this to the list of groups
                    'Users\Model\GroupsTable' =>  function($sm) {
                        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                        $gTable     = new GroupsTable($dbAdapter);
                        return $gTable;
                    },
            ),
    );
}

次に、コントローラーで、サービスへの参照を取得しました。

$users = $this->getServiceLocator()->get('Test\Model\TestGroupTable')->fetchAll();
        $options = array();
        foreach ($users as $user)
           $options[$user->id] = $user->name;
        //get the form element
        $form->get('user_id')->setValueOptions($options);

そしてヴィオラ、その作品。

于 2014-01-20T11:04:16.410 に答える
0

フォームを受け入れるメソッドを追加することにより、モデルでこれを処理します

public function buildFormSelectOptions($form, $context = null)
{
    /** 
     * Do this this for each form element that needs options added
     */
    $model = $this->getServiceManager()->get('modelProject');

    if (empty($context)){
        $optionRecords = $model->findAll();
    } else {
        /**
         * other logic for $optionRecords
         */
    }

    $options = array('value'=>'', 'label'=>'Choose a Project');
    foreach ($optionRecords as $option) {
        $options[] = array('value'=>$option->getId(), 'label'=>$option->getName());
    }

    $form->get('project')->setAttribute('options', $options);
}

フォームは参照によって渡されるため、フォームが構築されているコントローラーで次のようなことができます。

    $builder = new AnnotationBuilder();
    $form = $builder->createForm($myEntity);
    $myModel->buildFormSelectOptions($form, $myEntity);

    $form->add(array(
        'name' => 'submitbutton',
        'attributes' => array(
            'type'  => 'submit',
            'value' => 'Submit',
            'id' => 'submitbutton',
        ),
    ));

    $form->add(array(
        'name' => 'cancel',
        'attributes' => array(
            'type'  => 'submit',
            'value' => 'Cancel',
            'id' => 'cancel',
        ),
    ));

注: この例では、ベース フォームが注釈を介して構築されていることを前提としていますが、初期フォームをどのように作成するかは問題ではありません。

于 2012-11-10T21:39:10.720 に答える
0

他の回答に代わる方法は、ServiceManager Initializer を作成することです。

既存の Initializer の例は、インスタンスが ServiceLocatorAwareInterface を実装している場合に ServiceManager がどのように注入されるかです。

アイデアは、イニシャライザでチェックするインターフェイスを作成することです。このインターフェイスは次のようになります。

interface FormServiceAwareInterface
{
    public function init();
    public function setServiceManager(ServiceManager $serviceManager);
}

Initializer がどのように見えるかの例:

class FormInitializer implements InitializerInterface
{
    public function initialize($instance, ServiceLocatorInterface $serviceLocator)
    {
        if (!$instance instanceof FormServiceAwareInterface)
        {
            return;
        }

        $instance->setServiceManager($serviceLocator);
        $instance->init();
    }
}

で発生するものはすべて、init()にアクセスできますServiceManager。もちろん、初期化子を SM 構成に追加する必要があります。

完璧ではありませんが、私のニーズには問題なく機能し、ServiceManager から取得したフィールドセットにも適用できます。

于 2012-11-28T15:59:38.200 に答える