2012-09-17 8 views
16

フォームからアダプタを取得する必要がありますが、それでも解決できません。私のコントローラでZend FrameWork 2 Form内でServiceLocatorを取得し、ドロップダウンリストを設定します

私が使用してアダプタを回復することができ、次の私のモジュールで

// 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(see this link)でuserFormクラス内のサービスを取得する必要があります。デフォルトでは、Zend Framework MVCは、ServiceManagerインスタンスに挿入される初期化子を登録するためServiceLocatorAwareInterfaceを実装しています。

テーブルグループから値を取得して、選択に入力した後。

問題は、私が試したすべての方法、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... 
+2

こんにちは、あなたはこれの解決策を見つけましたか? –

答えて

1

module.phpで私は2つのサービスを作成します。フォームにアダプタをどのように供給するかを見てください。

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'); 
     } 

    } 
} 
+0

私の質問を編集しました。私は今、理解することがより明確だと信じています。お返事をありがとうございます。 – JulianoMartins

+0

selectオプションを設定するには、私の答えに書かれているように、モデル(または他のクラス/アダプタ/何でも)をフォームに渡します。その後、あなたはそれと対話することができます。 – michaelbn

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); 
} 

形態を受け入れる方法を追加することによって、モデルでこれを処理する:私は何にそのフィードを使用して、フォームコードで

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')); 
      }, 

     ), 
    ); 
} 

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

$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', 
     ), 
    )); 

注:この例では、基本フォームがアノテーションを使用してビルドされていることを前提としていますが、初期フォームの作成方法は問われません。

6

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

まず、前と同じように、フォームにServiceLocatorInterfaceを実装したいとします。

その後、まだ手動でサービスロケータを注入する必要がありますが、全体の形がcontrstuctor内部で生成されたとして、あなたも(ただし、コンストラクタでそのすべてを構築することがない理想的な)コンストラクタ

を経由して注入する必要があります。

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'); 

を今、あなたはFUにアクセスする必要があります次のような他のサービスを取得するために、フォーム内のサービスロケータを使用します。

$groups = $this->getServiceLocator()->get('Users\Model\GroupsTable')->fetchAll(); 
+1

私はこの回答が一番好きでしたが、サービスロケータをフォームの中に保存することは実際にはメモリが重いことに気づいたので、フォームの中に保存する代わりに、コンストラクタで渡します。設定して保存しないでください。 – gmaliar

+0

私はあなたと一緒にそこにいます、それは本当に迷惑です... Zendがうまくそれを修正したのを見てうれしく思います。 –

+0

オブジェクト内の単なる参照は「メモリが重い」ではありません。 – AsTeR

0

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

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

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

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

あなたの初期化子のように見えるかもしれないものの例:

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

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

init()で発生するものは、ServiceManagerにアクセスできます。もちろん、SM構成にイニシャライザを追加する必要があります。

これは完璧ではありませんが、私のニーズに適しており、ServiceManagerから取得したフィールドセットにも適用できます。

7

ここでは、ZF < 2.1の他のさまざまな回答が一般的に正しくなります。

2.1がなくなると、フレームワークはかなりnice solutionになります。これはDrBezaの解決策を多かれ少なかれ公式化しています。すなわち、イニシャライザを使用し、すべての依存関係が初期化された後に呼び出されるinit()メソッドにフォームブートストラップを移動します。

私は開発ブランチで遊んできました。それはとてもうまく動作します。

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); 

をとビオラ、その作品。

関連する問題