4

ZF2 でフォームを作成しようとしています。問題は、データベース テーブルから Select 入力要素のオプション配列を設定したいときに発生します。この質問への応答Zend FrameWork 2 Get ServiceLocator In Form and populate a drop down list by @timdev は、「正しい」メソッドが記述されている ZF2 ドキュメントを示しました。私はこれに注意深く従いましたが、ギャップを埋めることができると仮定して、それを機能させることができないため、明らかなコードを除外したに違いないと思います。誰かが私が間違っていることを見ることができますか?

フィールドセットを追加するフォームから始めます。

namespace Ctmm\Form;
use Zend\Form\Form;

class AddPropertyForm extends Form {

public function __construct() {

    parent::__construct('AddProperty');

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

    $this->add(array(
        'name' => 'property',
        'type' => 'PropertyFieldset'
    ));

} }

次に、フィールドセットを作成します。

namespace Ctmm\Form;
use Ctmm\Model;
use Zend\Form\Fieldset;

class PropertyFieldset extends Fieldset { 

public function __construct(PropertyType $property_type) {
    $this->add(array(
        'name' => 'property_type',
        'type' => 'Zend\Form\Element\Select',
        'attributes' => array(
            'required' => true,
        ),
        'options' => array(
            'label' => 'Property Type',
            'value_options' => array(
                0 => 'Detached house',
                1 => 'Semi-detached house',
                2 => 'Terraced house',
                3 => 'Bungalow',
                4 => 'Maisonette',
                5 => 'Flat',
                6 => 'Land',
                7 => 'Development Opportunity',
            ),
        ),
    ));

}

}

ご覧のとおり、PropertyType 依存関係をフィールドセットに挿入します。この段階では、これを使用してオプション配列を生成することさえしていません。可能性のあるエラーの別のソースを追加しないように、配列値をハードコーディングしました。レンダリングするフォームを取得したら、PropertyType テーブルから配列データを取得しようとします。

ここで、Module.php でフォーム要素マネージャーをセットアップします。

namespace Ctmm;
use Ctmm\Form\PropertyFieldset;
use Zend\ModuleManager\Feature\FormElementProviderInterface;

class Module implements FormElementProviderInterface {

public function getFormElementConfig() {
    return array(
        'factories' => array(
            'PropertyFieldset' => function($sm) {
                $serviceLocator = $sm->getServiceLocator();
                $property_type = $serviceLocator->get('Ctmm\Model\PropertyType');
                $fieldset = new PropertyFieldset($property_type);
            }
        )
    );
}

}

このコードはドキュメントからそのままです。追加してみました

return $fieldset;

PropertyFieldset ファクトリに追加してみました。

'invokables' => array(
'PropertyFieldset' => 'Ctmm\Form\PropertyFieldset'
)

getFormElementConfig 配列に追加し、ファクトリを呼び出し可能なものに置き換えます。

最後のステップは、フォーム要素マネージャーを使用してコントローラー アクションでフォームを作成することです。

public function addAction() {        
$formManager = $this->serviceLocator->get('FormElementManager');
    $form        = $formManager->get('Ctmm\Form\AddPropertyForm');
}

何をしても、Servicemanager が PropertyFieldset を作成できないというエラーが表示されます。

Zend\ServiceManager\Exception\ServiceNotFoundException

ファイル:

/home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:456

メッセージ:

Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for PropertyFieldset

スタックトレース:

#0 /home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php(103): Zend\ServiceManager\ServiceManager->get('PropertyFieldse...', true)
#1 /home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/Form/Factory.php(110): Zend\ServiceManager\AbstractPluginManager->get('PropertyFieldse...')
#2 /home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/Form/Form.php(145): Zend\Form\Factory->create(Array)
#3 /home/mike/public_html/ctmm/module/Ctmm/src/Ctmm/Form/AddPropertyForm.php(33): Zend\Form\Form->add(Array)

AddPropertyForm.php の 33 行目で、カスタム PropertyFieldset を追加しようとしています。明らかに、フィールドセット自体またはそれを宣言する方法にエラーがあります。PropertyType 依存関係を注入せずに試してみましたが、違いはありません。完全を期すために、私の PropertyType モデルのコードは次のとおりです。

namespace Ctmm\Model;

class PropertyType {
public $id;
public $property_type;
protected $adapter;

public function __construct($adapter) {
    $this->adapter = $adapter;
}

public function exchangeArray($data) {
    $this->id = (isset($data['id'])) ? $data['id'] : null;
    $this->property_type = (isset($data['property_type'])) ? $data['property_type'] : null;
}

public function getPropertyType() {
    return $this->property_type;
}

public function fetchAll() {

    $sql_query = "SELECT id, property_type from property_type";
    $statement = $this->adapter->createStatement($sql_query);
    $results = $statement->execute();
    return $results;
}

}

編集:

答えはありませんが、さらに調査を行いました。PropertyFieldset クラスと依存モデルをテストするために、コントローラーでフィールドセットを直接作成しました。

$property_type = $this->getServiceLocator()->get('Ctmm\Model\PropertyType');
$fieldset = new PropertyFieldset($property_type);

これはすぐには機能しませんでした。まず、Fieldset コンストラクターからヒントを取得する必要がありました。

public function __construct(PropertyFieldset $property_type) {

なりました

public function __construct($property_type) {

その後、追加する必要がありました

parent::__construct('propertyfieldset');

要素を追加できるようになる前に。

これらの変更を追加すると、コントローラーで PropertyFieldset オブジェクトを作成できるようになりました。これを var_dump()ing することでテストできます。

残念ながら、PropertyFieldset クラスへのこれらの変更では基本的な問題は解決されなかったため、コントローラーでフォームを作成しようとすると、以前と同じエラーが発生します。私は、少なくとも PropertyFieldset クラスを免罪しました。これは依存モデルであり、Module.php クラスの getFormElementConfig() に何か問題があると言っています。

4

1 に答える 1

6

そのため、いくつかの小さな変更を加えてこれを機能させました。

ご指摘のとおり、次のPropertyFieldSetように親コンストラクトを呼び出す必要があります。

parent::__construct('propertyfieldset'); 

ElementConfig は次のようになります。

public function getFormElementConfig() {
    return array(
        'factories' => array(
            'PropertyFieldset' => function($sm) {
                $serviceLocator = $sm->getServiceLocator();
                $property_type = $serviceLocator->get('Ctmm\Model\PropertyType');
                $fieldset = new PropertyFieldset($property_type);
                return $fieldset;
            },
        )
    );
}

AddPropertyForm は次のようになります。

namespace Ctmm\Form;
use Zend\Form\Form;

class AddPropertyForm extends Form {

    public function init() {

        parent::__construct('AddProperty');

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

        $this->add(array(
            'name' => 'addproperty',
            'type' => 'PropertyFieldset',
        ));
    }
}

__construct を使用する代わりに、init() を使用します。この関数は、ファクトリによってインスタンス化されたときに呼び出されるようです: http://framework.zend.com/apidoc/2.1/classes/Zend.Form.Form.html#init

選択の構築に関しては、モデルの代わりに TableGateway オブジェクトを fieldSet に渡します。次に、fetchAll 関数を使用して、次のフォームを実行できます。

class PropertyFieldset extends Fieldset {

    public function __construct(PropertyTypeTable $propertyTypeTable) {
        parent::__construct('propertyfieldset');


        $propertyValOpts = array();
        foreach($propertyTypeTable->fetchAll() as $propertyRow) {
            array_push($propertyValOpts,$propertyRow->property_type);
        }

        $this->add(array(
            'name' => 'property_type',
            'type' => 'Zend\Form\Element\Select',
            'attributes' => array(
                'required' => true,
            ),
            'options' => array(
                'label' => 'Property Type',
                'value_options' => $propertyValOpts
            ),
        ));
    }
}

お役に立てれば :)

于 2013-03-16T18:09:08.003 に答える