2012-04-10 23 views
11

Ho una vista e voglio usare una pagina di layout. Nella pagina di layout voglio avere un banner condizionale che parte della vista si accenderà/spegnerà. Mi chiedo solo come posso fare questo?Come posso impostare una variabile su una pagina _Layout?

ho questo nella pagina _Layout.cshtml ...

@if (ShowBanner){ 

    <h1>banner</h1> 

} 

Mi chiedo come posso girare questo on/off dalla mia pagina MVC View? O se questa è la cosa giusta da fare a tutti? Voglio dire se dichiaro quella variabile nella pagina Vista sicuramente il master non lo sa? Come comunicano i due attraverso C#? Uso il Viewbag? Piuttosto no.

so che con forme tutti i suoi circa riferimento al membro pagina o master, appena cant abbastanza sembrano vederlo con MVC ...

Qualsiasi aiuto molto apprezzato ...

Grazie Pete

risposta

12

Sono con te, Exitos: evito usando ViewBag troppo. A parte il nome sciocco, non mi piace la digitazione debole che ne deriva. C'è una soluzione, ma è un po 'coinvolta, quindi abbi pazienza con me.

Innanzitutto, creare una classe per memorizzare i "suggerimenti di visualizzazione" che devono essere passati al layout. Io chiamo questo modo creativo di classe "DisplayHints":

public class DisplayHints { 
    // anything that you want passed from a view to the layout goes here 
    public bool ShowBanner { get; set; } 
} 

Poi, creare una classe derivante dalla WebViewPage<T> che sarà la nuova classe di base dei vostri punti di vista. Si noti come abbiamo una proprietà chiamata DisplayHints che è memorizzato in ViewData (che è disponibile per il controller, la vista, e il layout):

public abstract class MyViewPage<T> : WebViewPage<T> { 
    public DisplayHints DisplayHints { 
    get { 
     if(!ViewData.ContainsKey("DisplayHints")) 
     ViewData["DisplayHints"] = new DisplayHints(); 
     return (DisplayHints)ViewData["DisplayHints"]; 
    } 
    } 
} 

Come un commentatore ha sottolineato di seguito, ViewData è debolmente tipizzato, proprio come ViewBag. Tuttavia, non c'è modo di sapere per evitare di memorizzare qualcosa in ViewData/ViewBag; questo riduce al minimo il numero di variabili debolmente tipizzate a una. Dopo averlo fatto, è possibile memorizzare tutte le informazioni fortemente tipizzate in DisplayHints come si desidera.

Ora che si dispone di una classe di base per le vostre opinioni, in Web.config, abbiamo bisogno di dire a MVC di utilizzare la classe di base personalizzato:

<pages pageBaseType="MyNamespace.Views.MyViewPage"> 

Suona come un sacco di problemi, ma si guadagna qualche grave funzionalità per tutto questo lavoro. Ora a suo avviso, è possibile impostare qualsiasi suggerimento di visualizzazione che si desidera nel modo seguente:

@{ DisplayHints.ShowBanner = true; } 

E nel layout, è possibile accedervi con la stessa facilità:

@if(DisplayHints.ShowBanner) { 
    <div>My banner....</div> 
} 

Spero che questo aiuta!

+0

Interessante, ma ViewData ha ancora gli stessi deboli problemi di digitazione di ViewBag e si è trattato di molti più problemi per arrivarci. – Maess

+0

Mi piace questa soluzione .. e non penso che sia un "problema in più" estendere la 'WebViewPage' – MilkyWayJoe

+0

Maess, sì,' ViewData' ha gli stessi deboli problemi di digitazione di 'ViewBag'. Tuttavia, invece di salvare una serie di suggerimenti per la visualizzazione come variabili debolmente tipizzate, si salva solo un oggetto, in cui è possibile inserire tutte le cose fortemente tipizzate che si desidera, comprese le strutture più complicate. Nella mia applicazione, la classe 'DisplayHints' contiene oltre venti membri ... tutti fortemente digitati. –

3

Avere un modello per il proprio layout non è una buona idea in quanto obbligherà tutte le viste a utilizzare quel modello. Tuttavia, è possibile inserire questo tipo di informazioni nel ViewBag e inserire il valore nel costruttore di una delle basi del controller.

+1

Si potrebbe persino avere un controller di base che inserisce sempre la variabile in ViewBag – Joe

+0

Naturalmente, non ero sicuro che l'OP usasse sempre la stessa base di controller. – Maess

+0

se è possibile inserire la variabile nel viewbag, perché non si può inserire fortemente nel controller stesso? Le viste – liang

-1

provare qualcosa di simile:

sul controller

var yourVariable; 
// other stuff and eventually fill the 'yourVariable' variable 
ViewBag.YourVariable = yourVariable; 

poi sulla vostra vista

@if (ViewBag.YourVariable){ 

    <!-- Your markup --> 

} 
Problemi correlati