Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
368 views
in Technique[技术] by (71.8m points)

php - Create a drop down list in Zend Framework 2

I know this sounds much more basic, still I want to post my question as it is related to Zend Framework 2. I know this form from the Zend example module

namespace AlbumForm;

use ZendFormForm;

class AlbumForm extends Form
{
    public function __construct($name = null)
    {
        // we want to ignore the name passed
        parent::__construct('album');
        $this->setAttribute('method', 'post');
        $this->add(array(
            'name' => 'id',
            'attributes' => array(
                'type'  => 'hidden',
            ),
        ));
        $this->add(array(
            'name' => 'artist',
            'attributes' => array(
                'type'  => 'text',
            ),
            'options' => array(
                'label' => 'Artist',
            ),
        ));
        $this->add(array(
            'name' => 'title',
            'attributes' => array(
                'type'  => 'text',
            ),
            'options' => array(
                'label' => 'Title',
            ),
        ));
        $this->add(array(
            'name' => 'submit',
            'attributes' => array(
                'type'  => 'submit',
                'value' => 'Go',
                'id' => 'submitbutton',
            ),
        ));
    }
}

And this is called in this fashion

<?php
$form = $this->form;
$form->setAttribute('action', $this->url('album', array('action' => 'add')));
$form->prepare();

echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('title'));
echo $this->formRow($form->get('artist'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();

How can I add a drop down list for the artist field where the list is stored in an associative array. Since Im getting into Zend Framework 2, I wanted the suggestions from the experts. I have followed this previous post but it was somewhat unclear to me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is one way to do it for static options.

....

$this->add(array(
    'type' => 'ZendFormElementSelect',
    'name' => 'number'
    'options' array(
        'options' => array( '1' => 'one', '2', 'two' )
    )
));

Be warned....

Because you are creating the form within a constructor you will not have access the ServiceManger. This could cause a problem if you want to populate from a database.

Lets try something like...

class AlbumForm extends Form implements ServiceManagerAwareInterface
{

public function __construct()
{
    ....

    $this->add(array(
        'type' => 'ZendFormElementSelect',
        'name' => 'number'
    ));

    ....
}

....

public function initFormOptions()
{
    $this->get('number')->setAttribute('options', $this->getNumberOptions());
}

protected function getNumberOptions()
{
    // or however you want to load the data in
    $mapper = $this->getServiceManager()->get('NumberMapper');
    return $mapper->getList();
}

public function getServiceManager()
{
    if ( is_null($this->serviceManager) ) {
        throw new Exception('The ServiceManager has not been set.');
    }

    return $this->serviceManager;
}

public function setServiceManager(ServiceManager $serviceManager)
{
    $this->serviceManager = $serviceManager;
}

But that's not great, rethink...

Extending the Form so that you can create a form isn't quite right. We are not creating a new type of form, we are just setting up a form. This calls for a factory. Also, the advantages of using a factory here are that we can set it up in a way in which we can use the service manager to serve it up, that way the service manager can inject itself instead of us doing in manually from the controller. Another advantage is that we can invoke this form whenever we have the service manager.

Another point worth making is that where it makes sense, I think it's better to take code out of the controller. The controller is not a script dump so it's nice to have objects look after themselves. What I'm trying to say is that it's good to inject an object with objects it needs, but it's not okay to just hand it the data from the controller because it creates too much of a dependency. Don't spoon feed objects from the controller, inject the spoon.

Anyway, too much rant more code...

class MySpankingFormService implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceManager )
    {
        $mySpankingNewForm = new Form;

        // build that form baby,
        // you have a service manager,
        // inject it if you need to,
        // otherwise just use it.

        return $mySpankingNewForm;
    }
}

controller

<?php

class FooController
{
    ...
    protected function getForm()
    {
        if ( is_null($this->form) ) {
            $this->form =
                $this->getServiceManager()->get('MySpankingFormService');
        }
        return $this->form;
    }
    ...
}

module.config.php

...
'service_manager' => array (
        'factories' => array (
            ...
            'MySpankingFormService'
                => 'MyNameSpacingFooMySpankingFormService',
            ...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...