2017-06-02 1 views
0

Wir sind es gewohnt, mit ZF2 zu arbeiten, aber für unser letztes Projekt haben wir uns entschieden, mit ZF3 zu beginnen.
Jetzt habe ich ein Problem bei der Formularerstellung.Zend framework 3 benutzerdefinierte Elemente

Was ich tun möchte, ist eine benutzerdefinierte Auswahl erstellen mit Daten aus der Datenbank abgerufen gefüllt.

Was ich in ZF2 tat, war eine Klasse erstellt eine Auswahl erstreckt, mit dem ServiceLocatorAwareInterface, wie:

class ManufacturerSelect extends Select implements ServiceLocatorAwareInterface { 

    public function init() { 
     $manufacturerTable = $this->getServiceLocator()->get('Car\Model\ManufacturerTable'); 
     $valueOptions = []; 
     foreach ($manufacturerTable->fetchAll() as $manufacturer) { 
      $valueOptions[$manufacturer->getManufacturerId()] = $manufacturer->getName(); 
     } 
     $this->setValueOptions($valueOptions); 
    } 

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

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

} 

Dann wird in einer Form zu verwenden, war es genug, um den vollständigen Namen

zu geben
$this->add(
    array(
     'name' => 'manufacturer_id', 
     'type' => 'Car\Form\Element\ManufacturerSelect' 
    ) 
); 

Jetzt ist dies nicht mehr möglich, da der Service Locator entfernt wurde und die Verwendung von Fabriken notwendig ist, aber ich habe Mühe zu finden, wie das Gleiche zu tun.

Wenn man bedenkt, Fabriken zu verwenden, habe ich versucht, diese Konfiguration in module.config.php:

'form_elements' => [ 
    'factories' => [ 
     'Car\Form\Element\ManufacturerSelect' => function ($services) { 
      $manufacturerTable = $services->get('Car\Model\ManufacturerTable'); 
      return new ManufacturerSelect($manufacturerTable); 
     }, 
     'Car\Form\CarForm' => function ($services) { 
      $manufacturerTable = $services->get('Car\Model\ManufacturerTable'); 
      return new CarForm($manufacturerTable, 'car-form'); 
     } 
    ] 
] 

Ergebnis: Fabrik von CARFORM wird immer dann aufgerufen, aber Fabrik von ManufacturerSelect nicht.

Eine einfache Lösung wäre, die Auswahl direkt in der Formularklasse zu füllen, aber ich würde lieber die Fabrik für das Element verwenden und es überall wiederverwenden, wie ich es in ZF2 gemacht habe.

Hat schon jemand dieses Problem gefunden und eine Lösung gefunden?

+0

Welche Fehler erhalten Sie? Und bitte verwenden Sie keine Closures, da die Fabriken http://zendframework.github.io/zend-servicemanager/migration/#factoryinterface -> Closures nicht cachefähig sind und nicht so wiederverwendbar wie Factory-Klassen sind. – Dymen1

+0

Eigentlich bin ich nicht Bei einem Fehler wird die Fabrik nicht aufgerufen. Ich bin mir 100% sicher, weil ich sogar einen Würfel hineingesteckt habe, ohne Erfolg. Über Verschlüsse habe ich sie nur zur Darstellung hier benutzt, normalerweise benutze ich Klassen. – Matteo

+0

Wie fügen Sie das Formular "Car \ Form \ Element \ ManufacturerSelect" zu Ihrem Formular hinzu? benutze immer noch '$ this-> add (['type' => class])'? – Dymen1

Antwort

0

Fügen Sie dieses Element in der Funktion "__construct" hinzu? Wenn ja versuchen „init“

EDIT:

Zunächst einmal brauchen Sie nicht eine benutzerdefinierte wählen füllen es über Datenbank zu erstellen. Erstellen Sie einfach ein Formular mit Factory, holen Sie Daten von db in der Fabrik und übergeben Sie sie an das Formular. Und verwenden Sie die Daten in der Formularklasse als Wertoptionen für die Auswahl.

$this-add([ 
    'type' => Element\Select:.class, 
    'name' => 'select-element' 
    'options' => [ 
     'label' => 'The Select', 
     'empty_option' => 'Please choose one', 
     'value_options' => $this-dataFromDB 
    ] 
]); 

Wenn Sie Formular erstellen, wie:

new MyForm(); 

Formular Element Manager keine benutzerdefinierten Elemente Fabriken auslösen. Aber;

$container->get('FormElementManager')->get(MyForm::class); 

löst benutzerdefinierte Elemente Fabriken. Hier ist ein funktionierendes Beispiel. Es arbeitet an ZF3.

Config:

return [ 
    'controllers' => [ 
     'factories' => [ 
      MyController::class => MyControllerFactory::class 
     ] 
    ], 
    'form_elements' => [ 
     'factories' => [ 
      CustomElement::class => CustomElementFactory::class, 
      MyForm::class => MyFormFactory::class, 
     ] 
    ] 
]; 

nicht vergessen 'Zend \ Form' auf die Anwendung config 'Module' hinzuzufügen.

Element:

class CustomElement extends Text 
{ 
} 

Element Factory:

class CustomElementFactory implements FactoryInterface 
{ 
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
    { 
     echo 'element factory triggered'; 
     return new CustomElement(); 
    } 
} 

Fieldset/Form:

class MyForm extends Form 
{ 
    public function init() 
    { 
     $this 
      ->add([ 
       'type' => CustomElement::class, 
       'name' => 'name', 
       'options' => [ 
        'label' => 'label', 
       ], 
      ]) 
     ; 
    } 
} 

Fieldset/Form Factory:

class MyFormFactory implements FactoryInterface 
{ 
     public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
     { 
      echo 'form factory triggered'; 
      return new MyForm(); 
     } 
} 

Kontrolleurs Factory:

class MyControllerFactory implements FactoryInterface 
{ 
     public function __invoke(ContainerInterface $container, $requestedName, array $options = null) 
     { 
      echo 'controller factory triggered'; 
      return new MyController(
        $container->get('FormElementManager')->get(MyForm::class); 
      ); 
     } 
} 
+0

Schon versucht, aber ohne Erfolg. – Matteo

+0

warten wie rufen Sie Formular? Sie müssen das Formular über FormElementManager aufrufen, damit die Fabriken funktionieren. new MyForm() funktioniert dort nicht. –

+0

Da es zwingend in ZF2 zu verwenden ist, verwende ich es auch in ZF3. Aber immer noch die Element Factory nicht aufgerufen (aber die Form Factory ist) – Matteo

Verwandte Themen