Sto utilizzando correttamente la libreria Form di Zend? (Sto effettivamente duplicando il lavoro in Controller e in View)

7

Breve riassunto

Questa domanda sta chiedendo indicazioni su come gestire la libreria Zend Form che mi consente di specificare come costruire ciascun elemento del modulo (lato Controller) e come rendere ogni elemento (lato Vista), essenzialmente creando 2x quantità di lavoro , se confrontato con un approccio non Zend-Form in cui ogni elemento del modulo viene trattato esattamente una volta - solo nella vista

Come fa il form Zend a fare cose

Sul mio Controller posso usare Zend Form per costruire ogni elemento del modulo. Nota: nel codice voglio mostrare che posso creare elementi HTML orientati agli oggetti e popolare i loro valori e attributi (compresi gli attributi CSS che voglio renderizzare in seguito) tutti all'interno del codice del controller a livello di codice.

Esposizione A - Lato controller modulo Zend

    //create checkbox
    $checkbox = new Element\Checkbox('construction');
    $checkbox->setLabel("Construction: ");
    $checkbox->setChecked(true);
    $checkbox->setAttribute('onclick', 'return false'); // disable checkbox

    // Set up
    $listPrice = new Element\Text('listprice');
    $listPrice->setLabel("List Price: ");
    $listPrice->setValue('123.00');
    $listPrice->setAttribute('disabled', 'disabled');
    $listPrice->setAttribute('style', 'color:black;text-align:right');
    $listPrice->setAttribute('size', 9);

    // Assemble Form
    $form = new Form('form');
    $form->add($checkbox);
    $form->add($listPrice);

    // return rendered HTML
    return $this->partial("form.phtml", array(
        'form' => $form
    ));

Poi nella mia vista

Voglio mostrare innanzitutto che in View, ZF2 a volte occupa la maggior parte del rendering del modulo HTML e non devo fare molto a volte. Ad esempio, potrei usare $this->form()->render($form) per eseguire il rendering di un intero modulo per me, ma non sarei in grado di posizionare lo stile personalizzato su ciascun elemento se lo desidera. E anche tutti gli elementi saranno resi in una singola riga, che è raramente quello che voglio.

Nel mio caso nel prossimo blocco di codice qui sotto ho dovuto approfondire e semi-automatizzare il rendering dei moduli, per poter aggiungere i miei elementi HTML come <p></p> durante il processo di rendering. cioè ho dovuto usare cose come openTag e closeTag e formRow metodi.

Oggetto B - Vista lato modulo Zend

/**
 * inside view template - with custom HTML 
 * custom HTML is one that contains form_row class
 * It will not render if I use $this->form()->form($form)
 * to render out complete form in one go.
 *
 * @var $this \Zend\View\Renderer\PhpRenderer
 * @var $form \Zend\Form\Form
 */
$form = $this->form;
?>
<style>
.form_row {
    margin-bottom: 14px;
    margin-top: 14px
}
</style>
<fieldset>
    <?php
    //renders <form ... >
    echo $this->form()->openTag($form);

    //loops through each form element, and passes it to "formrow" method
    //that renders out full element in HTML    
    foreach ($form as $element)
        $formContent .= '<p class="form_row">' . $this->formrow($element) . '</p>';

    echo $formContent;

    //renders </form>
    echo $this->form()->closeTag();
    ?>
</fieldset>

Ma più approfondisco, più codice devo scrivere. Se volessi personalizzare ogni elemento personalizzato, dovrei fare manualmente riferimento a ciascun elemento nella mia vista

Rendering di singoli elementi con stili personalizzati utilizzando Zend Form

<label>
    <span><?=$this->formLabel($form->get('listPrice'));?></span>
    <?=$this->formInput($form->get('listPrice'));=>
    <?=$this->formElementErrors($form->get('listPrice'));?>

    <div id="custom_form_div_between_elements">
        Custom div that would not be rendered inside this form, 
        if I left ZF2 on auto-pilot like in a previous example
    </div>

</label>

Immagina di fare quanto sopra per ogni elemento del modulo.

Quindi essenzialmente scrivo codice, definendo in modo programmatico gli elementi del modulo in Controller e quindi scrivendo il codice per renderli visibili nella vista. Doppio lavoro. Double Code.

Domanda

Mi dà fastidio che io molto spesso scriva codice due volte (sia per Controller che per View) per gestire ogni elemento del modulo.

Potrei invece fare meglio inserendo tutto nel mio script di visualizzazione come ad esempio

Esposizione C - Esempio che non utilizza Zend Form (rendering del mio elemento)

<label>
    <span>List Price: </span>
    <input name="listprice" disabled="disabled" 
        style="color:black;text-align:right" size="9" 
        value="<?=$price?>" type="text">
</label>

Esiste D - Completo 'codice reale' [seleziona] esempio quando non si utilizza Zend Form

<select name="id" id="modelid" class="validate[required]">
    <option>blank</option>
<?
$sql = "SELECT distinct(model), id FROM product GROUP BY model";
$result = db_query($sql);

for ($i = 0; $i < db_num_rows($result); $i ++)
{
    $row = db_fetch_array($result);
    ?>
    <option value="<?=$row['id']?>"
        <?=$productid == $row['id'] ? ' selected="selected"' : ''?>>
            <?=$row['model']?>
    </option>
    <?
}
?>
</select>

Riepilogo domanda

ZF2 mi consente di utilizzare il codice Zend Form per creare elementi modulo in Controller, popolarli con valori e quindi utilizzare varie strutture Zend per eseguire il rendering degli elementi nella vista. A seconda di quanto dettagliato vuoi ottenere (cioè se vuoi lo stile personalizzato per ogni elemento), stai facendo un bel po 'di lavoro per ogni elemento, che sembra duplicato: devi occuparti di ogni elemento nel tuo Controller e nella tua vista. Certo, un po 'di lavoro è più facile, cioè in un elemento <select> o <input type="radio"> non devi occuparti di hackerare PHP e HTML per assicurarti che una casella di selezione venga visualizzata con un valore particolare come selezionato. Zend si prende cura di questo per te.

Ora è bello se usi solo le funzioni di Zend Form native per generare tutto ciò che ti dà. Allora lavori solo su Controller. Ma nel momento in cui si desidera uno stile personalizzato, si esegue un lavoro aggiuntivo in Visualizza, a volte è sufficiente avere il codice tanto quanto il codice per ogni elemento del modulo nella vista, come nel controller.

Domande bonus

  • Quale problema risolve il modulo Zend dividendo Controller & Visualizza il codice? Sto usando questo correttamente? (Questo lavoro 2x è giustificato?)

  • Farò meglio a fare qualcosa come spostare tutto il controller del codice di Zend Form e avere tutto il "codice 2x" in diretta nella vista?

posta Dennis 25.02.2016 - 22:37
fonte

2 risposte

1

Gli esempi mostrati sono corretti, ma Zend \ Form non è esattamente ciò che si desidera utilizzare nei controller. Sto parlando di Exhibit A , dove mostra quanti codici creare, popolano e disegnano un modulo con due elementi. È noioso creare forme in questo modo.

Per evitare di trasformare il controller in una fabbrica di moduli, devi creare una fabbrica che creerà il modulo di cui hai bisogno (ad esempio AppFormFactory ). Quindi, il tuo controller dovrebbe apparire così:

$product = Model::getRandomProduct();
$form = AppFormFactory::create('ProductForm');
$form->bind($product);

Il codice relativo a Zend \ Form sarà all'interno dell'implementazione di AppFormFactory oppure puoi utilizzare Zend \ Form \ Factory per creare il modulo passando una matrice di configurazione invece di creare il modulo a livello di codice.

Un'altra cosa che vorrei sottolineare è che quando disponi di un modello e di un modulo configurato, come puoi vedere, puoi fare $form->bind($product) invece di impostare i valori di ogni elemento all'interno di un modulo. Ciò può essere utile quando si lavora con il modulo con molti elementi (ad esempio, modifica del modulo del prodotto).

Puoi anche usare annotazioni per creare un modulo con tutti i cablaggi (convalida, idratazione, ecc.), basta controllare l'ultima sezione di documentazione di Zend \ Form . Come commento finale, la parte stilistica (dimensione del carattere, colore) dovrebbe davvero essere solo parte di css.

    
risposta data 01.05.2016 - 19:21
fonte
0

Cercando gli esempi, credo che lo sto usando correttamente. Vale a dire che posso vedere alcuni vantaggi nell'usare Zend Form in quanto rende la vista più calda e più standardizzata e non era tanto lavoro quanto avevo inizialmente pensato.

La "massa" di impostazione di un elemento del modulo viene effettivamente spostata nel controller. In View, tutto ciò che fai è solo il rendering dell'etichetta e dell'elemento stesso usando le chiamate al metodo helper della vista Form di Zend, che sono le stesse per tutti gli elementi (standardizzati). Questo rende anche la vista più pulita. Quindi se qualcuno che non è un programmatore sta modificando la vista, non deve vedere o gestire il problema di "Mostra D" nella domanda.

Confronta qui sotto con "Mostra D" nella domanda.

Controller (modulo Zend)

    $result = $this->em->createQuery('SELECT m.name from Entity\Product m')
        ->getScalarResult();
    $options = array();
    foreach ($result as $key => $value)
        $options[$value['name']] = $value['name'];

    $productSelect = new Element\Select('product_name');
    $productSelect->setLabel('Product Name');
    $productSelect->setValueOptions($options);
    $productSelect->setValue('143AT');

Visualizza (modulo Zend)

    <?=$this->formLabel($form->get('product_name'));?>
    <?=$this->formSelect($form->get('product_name'));?>
    
risposta data 01.03.2016 - 18:33
fonte

Leggi altre domande sui tag