2011-01-15 11 views
8

Sono uno sviluppatore web e sono stato un programmatore per molto tempo. Ma non ho mai usato un'architettura MVC pura. Ora ho iniziato il mio progetto e ho deciso di creare html-css da solo e assumere un programmatore. Abbiamo scelto il popolare framework PHP-MVC.MVC: quanto codice deve essere in una vista?

I primi passaggi sono terminati, alcune pagine sono codificate. E dopo aver osservato il risultato ho la domanda ... quanto codice ci dovrebbe essere nei template (View)?

Per esempio, ecco un file di modello:

<?php $this->load->view('header'); ?> 
<?php $this->load->view('banner'); ?> 

<div id="items"> 
<?php 
for($i=0; $i<count($main); $i++) { 
    echo '<div class="item"> 
     <div class="name">'.$main[$i]['name'].'</div>'; 
    if($main[$i]['icq']=='') { } 
     else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; } 
    echo '</div>'; 
} 
?> 
</div> 

<?php $this->load->view('footer'); ?> 

Pensi che ci sia troppo codice in questo modello o è normale?

risposta

9

Non penso che quello che stai cercando di ottenere nella vista sia troppo logico, ma penso che dovrebbe essere pulito un po '.

Qualcosa di simile:

<?php foreach($main as $item): ?> 
<div class="item"> 
    <div class="name"><?php echo $item['name']; ?></div> 
    <?php if($item['icq']): ?> 
     <div class="phone"><?php echo $item['phone']; ?></div> 
    <?php endif; ?> 
</div> 
<?php endforeach; ?> 

trovo che molto più facile da leggere, e lo fa lo stesso lavoro. Inoltre, non penso che sarebbe difficile per un non codificatore modificare, che è in definitiva l'obiettivo di una vista.

+4

Se short_tags (php.ini) è abilitato, è possibile utilizzare anche "" Invece di

+3

Ho discusso se metterlo o meno, ma personalmente non mi piace affidarmi ai tag brevi: non so mai quando qualcuno li spegnerà su di te, e poi ti troverai in un mondo di guai. – sevenseacat

+1

Non li uso neanche ... ma credo che in codeigner funzionerebbero non importa se sono disattivati ​​apache ... – rabidmachine9

0

penso come James, troppo codice, ma è possibile aggiungere una variabile di matrice alle get_items() la funzione, per controllare il prefisso e suffisso di ogni elemento, qualcosa di simile a:

$options = Array('item_prefix' => '<div class="item">', 'item_suffix' => '</div>'...) 
echo get_items(); 
0

vostre opinioni dovrebbero sicuramente contiene la maggior parte dei tag html, quindi non penso che una funzione get_items debba essere posizionata da qualche altra parte. Basta ripulire un po 'i tuoi template e lavorare con la sintassi del loop alternativo come suggerito da Karpie. Potresti anche pensare di usare un motore di template esistente come Twig ma con questo le viste devono contenere anche dei riferimenti ai tuoi dati ... Quello che vuoi ottenere è che i non-programmatori possono modificare i tuoi file html senza dover capire troppa logica di scripting.

2

Quando i modelli bisogno di un sacco di logica è potrebbe essere utile introdurre il ViewModel pattern

La logica che determina quando un determinato blocco è mostrato viene inserito nel modello di vista.

Esempio
Un modello di frammento:

<?php if($item['show_phone_number']): ?> 
    <div class="phone"><?php echo $item['phone_number']; ?></div> 
<?php endif; ?> 

Una vista del modello frammento:

$item['show_phone_number'] = $item["icq"] == ''; 
+0

Questa risposta è sottovalutata: il modello ViewModel è ciò che deve essere visto qui. – Jimbo

1

risposta breve:

Il meno è in maniera economicamente sostenibile possibile.

16

La prima risposta era effettivamente visibile, ma l'utente l'ha cancellata (probabilmente a causa della pressione dei colleghi). Fondamentalmente, non vuoi nessuna logica nel tuo modello. In un mondo ideale, avevi un tag per tutti i dati del modello, ma dal momento che siamo in un mondo HTML, non c'è, quindi devi usare XSLT o usare ViewHelpers.

Concentriamoci sull'approccio ViewHelper.

Questo è difficile da mantenere:

<div id="items"> 
<?php 
for($i=0; $i<count($main); $i++) { 
    echo '<div class="item"> 
     <div class="name">'.$main[$i]['name'].'</div>'; 
    if($main[$i]['icq']=='') { } 
     else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; } 
    echo '</div>'; 
} 
?> 
</div> 

E non sarà niente di meglio se si sostituisce il PHP con Smarty. Questo è facile da mantenere:

<div id="items"> 
    <?php echo itemlist($items, 'template.htm') ?>; 
</div> 

Sotto la domanda ora cancellato, c'era una commentor contestare questo codice " non è facile da mantenere per i non programmatori perché ora non sanno dove ITEMLIST è definito e cosa fa." ma questo è senza senso. Pensaci per un secondo.

Da una parte, affermano che i non codificatori avranno problemi con una semplice chiamata di funzione, ma d'altra parte si aspettano che capiscano il guazzabuglio del codice PHP combinato con HTML. A un designer non interessa la logica della presentazione, ma solo la presentazione vera e propria. Il risultato.

Una singola chiamata di funzione dice chiaramente: "qui è un elenco di elementi", che è molto più facile da comprendere di "ecco un for che fa eco a un div e forse qualcos'altro se viene fornito icq". Una chiamata di funzione è valida come un tag. Ha input e output chiaramente definiti. Il modo in cui raggiunge quell'output è irrilevante per chiunque non sia lo sviluppatore.

ViewHelper incapsula la logica di presentazione. È uno snippet che puoi riutilizzare in tutte le tue visualizzazioni. Questo è molto più gestibile rispetto a copiare e incollare tutta la logica più e più volte quando necessario. Nell'esempio di cui sopra, ci sono due argomenti per l'aiutante:

  • $ articoli è un array o un altro tipo attraversabile tenendo i dati dell'articolo reale
  • 'template.htm' è il nome del modello utilizzato per il rendering i dati

Renderò il secondo opzionale, perché presumo che sia sempre lo stesso modello comunque. Ma dal momento che il commentatore si è lamentato che il non-codificatore non avrebbe saputo dove cercare, ho ritenuto necessario mostrare quanto sia facile dire al non-codificatore dove cercare.

function itemlist($items, $template = './templates/itemlist.htm') { 
    ob_start(); 
    foreach($items as $item) { 
     include $template; 
    } 
    return ob_get_flush(); 
} 

Ci potrebbero essere approcci più efficienti per risolvere l'inclusione del modello. L'idea principale dovrebbe essere chiara però. Nascondi la logica di presentazione dal modello attuale. Il tuo "template.htm" sarebbe quindi il seguente:

<div class="item"> 
    <div class="name"><?php echo $item['name'] ?></div> 
    <?php echo contact($item, 'icq' 'phone'); ?> 
</div> 

No if ed elses. Nessuna concatenazione di stringhe o parentesi graffe. La logica per decidere come contattare l'utente è nascosta anche in ViewHelper. Tutto ciò che il non-coder deve sapere ora sono gli argomenti per ViewHelpers ed è facile come sapere quale attributo scrivere su un tag. Dare loro un foglio cheat, se necessario.

Informazioni correlate:


EDIT

A causa delle due commenti qui sotto ho deciso di espandere su questa risposta. Quanto sopra non è un'astrazione per l'astrazione.È per la riusabilità e la manutenibilità. L'ho già detto sopra, ma lascia che ti spieghi di nuovo qui.

In realtà, trovo strano avere obiezioni sull'uso di ViewHelpers perché "avremo una presentazione in due punti" ma non mi lamento di separare intestazione, banner e piè di pagina. È la stessa cosa. Si isolano le parti riutilizzabili e le si inseriscono nei propri modelli. Separare la logica dal modello in quella fase è solo il naturale passo successivo per ottenere ancora più manutenibilità.

Un modello di vista che contiene la logica è effettivamente uno script e non un modello. Ogni modello di vista che contiene la logica per assemblarsi è destinato a ripetersi. Questo potrebbe non essere un problema con i siti di piccole dimensioni, ma se stai lavorando su un sito con un paio di dozzine o centinaia di viste e widget, non astrarre queste parti porterà alla duplicazione del codice. Metti tutta la logica nel modello e diventerà rapidamente un caos aggrovigliato di c & markup p'ed misto a condizionali. Per qualsiasi duplicazione, raddoppierai il tempo necessario per modificarlo. Aggiungi stili incorporati e Javascript invadente e sei in manutenzione hell.¹

Se usi OOP per le altre parti della tua applicazione, perché dovresti procedere proceduralmente alla tua vista? Se hai capito che dovresti separare Javascript e CSS dal tuo HTML, perché dovresti mischiare PHP nel tuo modello? Non ha senso. Lo snippet di codice dell'OP è uno script e non un modello. In quanto tale, è il dominio dello sviluppatore. E a causa di ciò applicate tutte le buone pratiche applicate anche ad altre parti della vostra applicazione. E questo include l'isolamento della logica in funzioni e/o classi.

Concesso, un designer che sta esaminando una sceneggiatura potrebbe non sapere immediatamente cosa sta succedendo. Ma poi di nuovo, potrebbe non saperlo neanche dopo aver iniziato ad aggiungere le funzioni native di PHP. Cosa sta facendo mb_strimwidth? E substr? Cos'è il costrutto ?:? Il PHP più reale che aggiungi, più difficile sarà leggere per i non sviluppatori.

Se si desidera che i progettisti lavorino sui modelli, non fornire loro script. Dai loro modelli E se lo fai, isolare la logica da esso e sostituirlo con chiamate di funzione facili da afferrare. Usa i nomi delle funzioni che comunicano chiaramente ciò che fa la funzione. Quindi il progettista ha solo bisogno di sapere se "Io uso questo con quell'input, otterrò sempre quell'output. Non m'importa come sarà quel risultato. Lo lascerò allo sviluppatore".

L'isolamento della logica in funzioni (o classi) offre inoltre il vantaggio immediato di poter testare la logica utilizzata per eseguire il rendering di parti specifiche su tale pagina separatamente. Non è necessario configurare l'intero ambiente richiesto per creare una pagina, ma basta inserire l'input richiesto e dichiararne l'output (ecco perché la funzione memorizza la stringa anziché emetterla btw).

¹ Per quelli di voi che pensano che questo non sia un problema, suggerisco caldamente di trovarsi un'applicazione legacy che mantenga davvero tutta la logica nel modello di visualizzazione. Prova a cambiare alcune cose. Una volta che hai avuto il piacere di mangiare attraverso 2500 linee di codice spaghetti con almeno 500 caratteri ciascuna e contenente un mix di PHP, HTML, CSS e JavaScript ripetuto, saprai di cosa sto parlando.

+5

Lo vedo come un'astrazione per l'astrazione. Sono tutto per separare la presentazione e il codice aziendale, ma ora hai una presentazione in due posizioni ('template.htm', e dovunque tu stia definendo' contact() '), e produci il buffering per ... cosa? Non ci dovrebbe essere nessuna logica aziendale in una vista, sì. La logica di presentazione è completamente diversa. – sevenseacat

+1

Completamente d'accordo, stai spostando la logica di visualizzazione fuori dalla vista, la mia domanda è: perché un 'non coder' dovrebbe guardarlo comunque? La maggior parte, se non tutti i progettisti che valgono la pena, comprendono il concetto di un if e un foreach. In realtà è più confuso e imprevedibile vedere una chiamata di funzione in una vista. – jondavidjohn

1

La visualizzazione non è un modello.

O almeno - non dovrebbe essere un modello. Le viste sono generalmente istanze di classi, che sono responsabili della gestione della logica di presentazione . Gestiscono più modelli e decidono quale utilizzare e quali dati passano in essi.

Ma CI non ha nulla di tutto questo.Sei fondamentalmente bloccato con un modello, che finge di essere "Visualizza", e le istanze di ActiveRecord, che ti dicono che sono "Modelli". Cavolo .. nel vero MVC il modello non è nemmeno una classe specifica ma un livello applicativo.

A lungo termine, questa situazione costringerà entrambe presentazione logica e la logica di business nel controller, mentre allo stesso tempo, la produzione di difficile da mantenere modelli e classi ActiveRecord.

Problemi correlati