ASP.NET MVC 3 – Modello di visualizzazione parziale vs modello di presentazione

Quindi, il titolo dovrebbe parlare da solo.

Per creare componenti riutilizzabili in ASP.NET MVC, abbiamo 3 opzioni (potrebbero essere altre che non ho menzionato):

Vista parziale:

@Html.Partial(Model.Foo, "SomePartial") 

Modello di editor personalizzato:

 @Html.EditorFor(model => model.Foo) 

Modello di visualizzazione personalizzato:

 @Html.DisplayFor(model => model.Foo) 

In termini di visualizzazione / HTML, tutte e tre le implementazioni sono identiche:

 @model WebApplications.Models.FooObject  

Quindi, la mia domanda è: quando / come decidi quale dei tre usare?

Quello che cerco davvero è una lista di domande da porsi prima di crearne una, per la quale è ansible utilizzare le risposte per decidere quale modello utilizzare.

Ecco le 2 cose che ho trovato meglio con EditorFor / DisplayFor:

  1. Rispettano le gerarchie dei modelli durante il rendering di helper HTML (ad esempio se hai un object “Bar” sul tuo modello “Foo”, gli elementi HTML per “Bar” saranno renderizzati con “Foo.Bar.ElementName”, mentre un partial avrà ” ElementName “).

  2. Più robusto, ad esempio se hai un List di qualcosa nel tuo ViewModel, potresti usare @Html.DisplayFor(model => model.CollectionOfFoo) , e MVC è abbastanza intelligente da vederlo come una raccolta e renderizzare il singolo display per ogni object (al contrario di un parziale, che richiederebbe un loop esplicito).

Ho anche sentito che DisplayFor rende un modello “di sola lettura”, ma non lo capisco – non potrei buttare un modulo lì?

Qualcuno può dirmi qualche altro motivo? C’è un elenco / articolo da qualche parte che confronta i tre?

EditorFor vs DisplayFor è semplice. La semantica dei metodi è generare le viste edit / insert e display / read only (rispettivamente). Utilizzare DisplayFor durante la visualizzazione dei dati (ovvero quando si generano div e span che contengono i valori del modello). Utilizzare EditorFor quando si modificano / inseriscono dati (ovvero quando si generano tag di input in un modulo).

I metodi di cui sopra sono incentrati sul modello. Ciò significa che prenderanno in considerazione i metadati del modello (ad esempio potresti annotare la tua class del modello con [UIHintAttribute] o [DisplayAttribute] e questo influenzerebbe il template che verrà scelto per generare l’interfaccia utente per il modello. modelli di dati (cioè modelli che rappresentano le righe in un database, ecc.)

D’altra parte Partial è view-centric in quanto sei principalmente interessato alla scelta della vista parziale corretta. La vista non ha necessariamente bisogno di un modello per funzionare correttamente. Può avere solo un set comune di markup che viene riutilizzato in tutto il sito. Ovviamente spesso si desidera influenzare il comportamento di questo parziale, nel qual caso si potrebbe voler passare in un modello di visualizzazione appropriato.

Non hai chiesto informazioni su @Html.Action che merita anche una menzione qui. Si potrebbe pensare ad una versione più potente di Partial in quanto esegue un’azione figlio del controllore e quindi esegue il rendering di una vista (che di solito è una vista parziale). Questo è importante perché l’azione figlio può eseguire una logica di business aggiuntiva che non appartiene a una vista parziale. Ad esempio potrebbe rappresentare un componente del carrello acquisti. La ragione per usarla è evitare di eseguire il lavoro relativo al carrello della spesa in ogni controller dell’applicazione.

In definitiva, la scelta dipende da cosa si sta modellando nella propria applicazione. Ricorda anche che puoi mescolare e abbinare. Ad esempio potresti avere una vista parziale che chiama l’helper EditorFor . Dipende davvero da cosa è la tua applicazione e da come tenerla in considerazione per incoraggiare il massimo riutilizzo del codice evitando la ripetizione.

È certamente ansible personalizzare DisplayFor per visualizzare un modulo modificabile. Ma la convenzione è che DisplayFor sia di readonly e che EditorFor sia per la modifica. Attenersi alla convenzione assicurerà che, indipendentemente da ciò che si passa a DisplayFor , farà lo stesso tipo di cosa.

Solo per dare il mio valore 2c, il nostro progetto utilizza una vista parziale con diverse tabs jQuery e ogni scheda mostra i suoi campi con la sua vista parziale. Questo ha funzionato fino a quando non abbiamo aggiunto una funzione in base alla quale alcune tabs condividevano alcuni campi comuni. Il nostro primo approccio a questo è stato quello di creare un’altra vista parziale con questi campi comuni, ma questo è diventato molto clunky quando si utilizza EditorFor e DropDownListFor per eseguire il rendering di campi e menu a discesa. Per ottenere gli id ​​e i nomi unici abbiamo dovuto rendere i campi con un prefisso dipendente dalla vista parziale genitore che lo stava restituendo:

   

Questo è diventato piuttosto brutto, quindi abbiamo deciso di utilizzare invece Editor Template, che ha funzionato molto più pulito. Abbiamo aggiunto un nuovo modello di vista con i campi comuni, aggiunto un modello di editor corrispondente e reso i campi utilizzando il modello di editor da diverse viste principali. Il modello di editor esegue correttamente gli id ​​e i nomi.

Quindi, in breve, un motivo convincente per noi di utilizzare Editor Template è stata la necessità di rendere alcuni campi comuni in più tabs. Le viste parziali non sono progettate per questo, ma i modelli di editor gestiscono perfettamente lo scenario.

Utilizzare l’approccio _partial view se:

  1. Visualizza la logica centrica
  2. Cosa tenere tutto l’HTML relativo alla vista _partial solo in questa vista. Nel metodo template, dovrai tenere un po ‘di HTML fuori dalla vista Template come “Main Header o qualsiasi confine / impostazioni esterni.
  3. Vuoi rendere la vista parziale con la logica (dal controller) usando URL.Action("action","controller") .

Motivi per utilizzare il modello:

  1. Vuoi rimuovere ForEach(Iterator) . Il modello è sufficiente per identificare il modello come un tipo di lista. Lo farà automaticamente.
  2. Modello Centric Logic. Se più viste vengono trovate nella stessa visualizzazione per la cartella Modello, il rendering dipenderà da Modello passato.

Un’altra differenza che non è stata menzionata finora è che una vista parziale non aggiunge i prefissi del modello mentre un modello fa il problema