2012-02-06 1 views
20

Ho un helper chiamato EditableArea che fornisce all'utente un modificabile in fase di esecuzione div (tramite JS). EditableArea controlli helper se un'area modificabile (non collegato al MVC di Area) con l'ID specificato esiste nel DB, in caso affermativo quindi rende HTML della zona, altrimenti visualizza markup predefinito specificato come parametro per l'helper:ASP.Net MVC3 - Passaggio del markup del rasoio come parametro

funziona tutto ok, ma mi piacerebbe cambiare in modo che il markup predefinito è specificato non come una stringa, ma nella sintassi rasoio, qualcosa di simile a:

@using (Html.EditableArea(someId)) 
{ 
    <p>Click to edit contents</p> 
} 

o qualcosa di simile, come il modo @section s lavoro in MVC3.

Come posso ottenere quello?

posso fare un IDisposable che in esso è Dispose chiude il TagBuilder, ecc, ma non posso evitare rendendo il codice Razor interno anche se l'helper trova una zona con un ID (posso cancellare il contenuto resi in Dispose() ma il codice all'interno di {} verrebbe comunque eseguito, cosa che vorrei saltare).

E se non uso using c'è un altro modo per passare un blocco del rasoio all'helper, che può o non può essere effettivamente visualizzato dall'assistente?

risposta

25

Ecco un esempio che uso per rendere jQuery markup Template passando in un modello di Id e la sintassi rasoio stile per il modello stesso:

public static MvcHtmlString jQueryTmpl(this HtmlHelper htmlHelper, 
    string templateId, Func<object, HelperResult> template) 
{ 
    return MvcHtmlString.Create("<script id=\"" + templateId + 
     "\" type=\"x-jquery-tmpl\">" + template.Invoke(null) + "</script>"); 
} 

e questo sarebbe stato chiamato con

@Html.jQueryTmpl("templateId", @<text>any type of valid razor syntax here</text>) 

in pratica basta usare Func<object, HelperResult> come parametro e template.Invoke(null) (con argomenti se necessario) per renderlo. Ovviamente si può saltare la chiamata a .Invoke() per evitare di rendere il markup "default".

+0

Non funziona. La sintassi ' ... 'all'interno della chiamata di funzione non viene riconosciuta (espressione non valida' <') –

+0

scusa, anteponiamo' 'con' @' (Ho aggiornato la mia risposta) –

+1

Ottimo, funziona ora.'I tag' 'non sono affatto necessari (' @ 'è sufficiente) a meno che il markup del rasoio sia in realtà testo normale senza tag, altrimenti solo' @ 'è sufficiente. –

3

Solo per espandere sulla risposta accettata, in quanto ci ho messo un po 'di tempo per risolvere un problema simile e questa è la domanda che spuntato. Quello che ho veramente bisogno era un @helper, che avrebbe accettato il testo rasoio, come il modello deve contenere un po 'di codice. Ho suonato in giro per un lungo durante il tentativo di utilizzare diverse versioni di tipo @helper item(Func<object, HelperResult> input), che ho trovato sul web, senza successo. Quindi sono andato per un approccio simile:

namespace project.MvcHtmlHelpers 
{ 
    public static class HelperExtensions 
    { 
     public static MvcHtmlString RazorToMvcString(this HtmlHelper htmlHelper, Func<object, HelperResult> template) 
     { 
      return MvcHtmlString.Create(template.Invoke(null).ToString()); 
     } 
    } 
} 

e

@project.MvcHtmlHelpers  
@helper item(other input, MvcHtmlString content) 
    { 
     <div class="item"> 
      ...other stuff... 
      <div class="content"> 
       @content 
      </div> 
     </div> 
    } 

e utilizzare questa via

@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>)) 

Ora posso utilizzare il modello di supporto sia per l'input del rasoio, ma posso anche rilasciare viste parziali, che è utile in alcuni punti. Poiché non sono esperto, potrebbero esserci opzioni migliori, ma mi sembra un approccio flessibile.