2011-01-26 23 views
32

Nuovo su MVC e hanno eseguito le esercitazioni sul sito Web asp.net.ASP.NET MVC 3 Helpers HTML personalizzati - Best practice/usi

Includono un esempio di un helper html personalizzato per troncare il testo lungo visualizzato in una tabella.

Basta chiedersi quali altre soluzioni le persone hanno escogitato utilizzando gli helper HTML e se ci sono delle best practice o cose da evitare durante la loro creazione/utilizzo.

Per fare un esempio, stavo considerando scrivere un aiuto personalizzato per formattare le date che ho bisogno di visualizzare in vari luoghi, ma sono ora preoccupati che ci possa essere una soluzione più elegante (DataAnnotations IE nei miei modelli)

qualche idea?

EDIT:

Un altro potenziale utilizzo ho solo pensato di ... concatenazione di stringhe. Un helper personalizzato può prendere un ID utente come input e restituire un nome completo agli utenti ... Il risultato potrebbe essere una forma di (Titolo) (Primo) (Medio) (Ultimo) a seconda di quali di questi campi sono disponibili. Solo un pensiero, non ho ancora provato niente del genere.

+0

Sono ancora interessato a vedere altre cose interessanti che le persone hanno fatto con gli helper HTML personalizzati. Sentiti libero di pubblicarli! – stephen776

risposta

16

Ebbene, nel caso di formattazione l'attributo DisplayFormat potrebbe essere una bella soluzione:

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")] 
public DateTime Date { get; set; } 

e poi semplicemente:

@Html.DisplayFor(x => x.Date) 

Per quanto riguarda il troncamento della stringa è interessato un aiutante HTML personalizzato è un buona soluzione.


UPDATE:

Per quanto riguarda la modifica, un aiutante HTML personalizzato potrebbe funzionare in questa situazione, ma c'è anche un approccio alternativo, che mi piace molto: visualizzare i modelli. Quindi, se in questo particolare vista si sta andando sempre a mostrare la concatenazione dei nomi allora si potrebbe definire un modello di vista:

public class PersonViewModel 
{ 
    public string FullName { get; set; } 
} 

Ora il regolatore sta per interrogare il repository per andare a prendere il modello e quindi mappare questo modello a un modello di vista che verrà passato alla vista in modo che la vista potrebbe semplicemente @Html.DisplayFor(x => x.FullName). La mappatura tra modelli e modelli di visualizzazione potrebbe essere semplificata con framework come AutoMapper.

+4

molto interessante. Sembra quasi che un helper html personalizzato sia l'ultima risorsa. – stephen776

100

Uso sempre HtmlHelpers, più comunemente per incapsulare la generazione di codice HTML, nel caso in cui cambi idea. Ho avuto tali aiutanti come:

  • Html.BodyId(): genera un tag ID corpo convenzionale per fare riferimento quando si aggiunge il css personalizzato per una vista.
  • Html.SubmitButton (stringa): genera un elemento di input [tipo = invio] o pulsante [tipo = invio], a seconda di come si desidera impostare i pulsanti.
  • Html.Pager (IPagedList): per generare controlli di paging da un modello di elenco a pagine.
  • ecc ....

Uno dei miei usi preferiti per HtmlHelpers è quello di ASCIUGARE il markup di modulo comune. Di solito, ho un div contenitore per una linea di modulo, un div per l'etichetta e un'etichetta per l'input, i messaggi di convalida, il testo di suggerimento, ecc. In definitiva, questo potrebbe finire per essere un sacco di tag html di boilerplate. Un esempio di come ho gestito questo segue:

public static MvcHtmlString FormLineDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string labelText = null, string customHelpText = null, object htmlAttributes = null) 
{ 
    return FormLine(
     helper.LabelFor(expression, labelText).ToString() + 
     helper.HelpTextFor(expression, customHelpText), 
     helper.DropDownListFor(expression, selectList, htmlAttributes).ToString() + 
     helper.ValidationMessageFor(expression)); 
} 

public static MvcHtmlString FormLineEditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string templateName = null, string labelText = null, string customHelpText = null, object htmlAttributes = null) 
{ 
    return FormLine(
     helper.LabelFor(expression, labelText).ToString() + 
     helper.HelpTextFor(expression, customHelpText), 
     helper.EditorFor(expression, templateName, htmlAttributes).ToString() + 
     helper.ValidationMessageFor(expression)); 
} 

private static MvcHtmlString FormLine(string labelContent, string fieldContent, object htmlAttributes = null) 
{ 
    var editorLabel = new TagBuilder("div"); 
    editorLabel.AddCssClass("editor-label"); 
    editorLabel.InnerHtml += labelContent; 

    var editorField = new TagBuilder("div"); 
    editorField.AddCssClass("editor-field"); 
    editorField.InnerHtml += fieldContent; 

    var container = new TagBuilder("div"); 
    if (htmlAttributes != null) 
     container.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 
    container.AddCssClass("form-line"); 
    container.InnerHtml += editorLabel; 
    container.InnerHtml += editorField; 

    return MvcHtmlString.Create(container.ToString()); 
} 

public static MvcHtmlString HelpTextFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string customText = null) 
{ 
    // Can do all sorts of things here -- eg: reflect over attributes and add hints, etc... 
}  

Una volta fatto questo, però, si può linee di forma output come questo:

<%: Html.FormLineEditorFor(model => model.Property1) %> 
<%: Html.FormLineEditorFor(model => model.Property2) %> 
<%: Html.FormLineEditorFor(model => model.Property3) %> 

... e BAM, tutte le etichette , input, suggerimenti e messaggi di convalida sono sulla tua pagina. Ancora una volta, è possibile utilizzare gli attributi sui modelli e riflettere su di essi per diventare davvero intelligenti e ASCIUTTI. E naturalmente questo sarebbe uno spreco di tempo se non è possibile standardizzare il design del modulo. Tuttavia, per casi semplici, in cui il css può fornire tutte le personalizzazioni necessarie, funziona grrrrrrrrrrreat!

Morale della storia - HtmlHelpers può isolarti dalle modifiche del design globale distruggendo il markup manuale in vista dopo la visualizzazione. Mi piacciono. Ma puoi andare in mare, e talvolta le viste parziali sono migliori degli aiutanti in codice. Una regola generale che uso per decidere tra la vista helper e quella parziale: se la porzione di HTML richiede un sacco di logica condizionale o di codice, io uso un helper (inserire il codice dove dovrebbe essere il codice); in caso contrario, se sto solo emettendo un markup comune senza molta logica, io uso una vista parziale (metti markup dove dovrebbe essere markup).

Spero che questo ti dia qualche idea!

+1

molto bello! un sacco di cose buone qui. – stephen776

+3

Ottimo post! Ne ho sicuramente copia/incolla alcuni da qui se non ti dispiace;) –

+7

Ottima risposta. Mi ci è voluto un po 'per capire che avevo bisogno di usando System.Web.Mvc.Html; per ottenere però l'estensione .EditorFor – Nick