2012-05-06 14 views
13

Sto solo imparando C# e MVC e sto cercando di capire alcuni esempi.@ Html.EditorFor (m => m) sintassi lambda in MVC

@Html.EditorFor(m => m) 

Alla fine ho capito che '=>' è l'operatore lambda, e che significa qualcosa come "m tale che m". Questo non ha alcun senso per me. Perché non passare in m?

Inoltre, non vedo m definito in nessuna vista con cui sto lavorando. Il modello è definito e presumibilmente questo è ciò che questo metodo sta rilevando. Come funziona?

Infine, ho esaminato la definizione di Html.EditorFor e non vedo alcun sovraccarico per il passaggio di un solo parametro. Dove viene definita questa sintassi ?? http://msdn.microsoft.com/en-us/library/ee834942.aspx

+2

"e non vedo sovraccarico per il passaggio di un solo parametro" - 'EditorFor' è un metodo di estensione, quindi stai cercando l'unico sovraccarico con due parametri, il primo è" questo ". – hvd

+2

Anche una cosa che consiglierei di creare un sito in mvc3 è di usare i tipi specifici di editor come '@ Html.TextBoxFor (m => m.name)' questo è così che se vuoi un valore predefinito funzionerà. Dove io (almeno) non sono stato in grado di assegnarlo a un 'EditorFor'. Anche TextBox/TextArea supporta i segnaposto tra le altre cose in cui 'EditorFor' non lo fa. così potresti fare '@ Html.TextBoxFor (m => m.Name, new {placeholder =" John Doe "})' e mvc implementerà automaticamente un segnaposto nei browser che lo supportano. – Jared

risposta

18

Rompiamo questo giù esaminando la firma del metodo:

MvcHtmlString EditorFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression 
) 

Questo sta usando metodo di estensione della sintassi, che significa che è l'aggiunta di un metodo denominato EditorFor a HtmlHelper tale che è possibile effettuare la chiamata Html.EditorFor. Ma ciò che siamo davvero interessa è il secondo parametro, Expression<Func<TModel, TValue>>. Questo è un parametro piuttosto complicato, ma per ora possiamo ignorare il fatto che si tratta di un Expression. Quindi semplificando, esaminiamo:

Func<TModel, TValue> expression 

Ciò significa che l'argomento è qualsiasi metodo che ha un parametro (di tipo TModel) e il tipo di ritorno è TValue. Hai usato lambda, che è (essenzialmente) una rappresentazione più concisa di un metodo, ma è utile considerarlo semplicemente come un metodo normale. Quindi sei lambda sta prendendo un modello e il ritorno di un modello:

m => m 

Questo non è così interessante, quindi cerchiamo di confrontarlo con uno scenario più realistico in cui si sta tornando una proprietà fuori del modello:

m => m.MyStringProperty 

Ora confrontiamo con un metodo statico ordinario hai dichiarato da qualche parte:

public static class MyStaticClass 
{ 
    public static string Foo(TModel model) 
    { 
     return model.MyStringProperty; 
    } 
} 

Anche se in realtà qui non sarebbe TModel - sarebbe tutto ciò che dichiarato il tuo tipo di modello tramite @model. Ora, per il bene della discussione, si potrebbe avere invece usato questo metodo nella vostra invocazione EditorFor:

Html.EditorFor(MyStaticClass.Foo); 

Quindi, per riassumere, lambda sono (per la maggior parte) solo una breve mano per un metodo regolare. Quindi tutto quello che stai facendo è passare i metodi.

L'ultima nota è che in realtà stiamo usando gli alberi di espressione, il che significa che non si sta passando il metodo, si passa un modello di oggetto (un albero di espressioni) che rappresenta il codice del metodo. Questo è, in sostanza, appena usato per capire il nome della proprietà che stai usando (perché di solito il lambda sarebbe più simile a m => m.MyProperty, non solo a m => m). Tutto questo per evitare stringhe magiche in cui ci si riferisce al nome della proprietà usando una stringa (ad esempio "MyProperty").

+1

wow, risposta stupenda! La parte che mancavo era che devi usare un'espressione che è un nome di metodo che restituisce un modello. Il tuo esempio con MyStaticClass è stato molto utile per comprendere questo concetto. –

3
  1. Nel tuo esempio, la funzione lambda non serve alcuno scopo, vero. Ma il suo vero uso è quando vuoi rendere l'editor per una proprietà del modello: @ Html.EditorFor (m => m.SomeProperty). Le espressioni Lambda sono in realtà solo una scorciatoia per le funzioni, ma fortemente digitate tramite delegates. Il concetto potrebbe essere più familiare da Javascript:

    myFunction (funzione (x) {return x.SomeProperty;});

  2. La "m" non è predefinita. Assegna un nome al parametro per la seconda parte dell'espressione lambda e potrebbe essere qualsiasi cosa: @ Html.EditorFor (qualunque sia => qualunque cosa). (Si riferisce alla stessa cosa, in questo caso il modello della pagina, indipendentemente da come lo chiami.)

  3. Il primo parametro che vedi in queste definizioni per Html.EditorFor non è realmente un parametro. Noterai che stanno utilizzando la parola chiave questa per definire extension methods. Questo parametro fa riferimento all'oggetto che ha invocato il metodo, in questo caso l'oggetto HtmlHelper <>.

+0

3. Molto utile, non ho notato/rendersi conto che stava passando "questo" come primo parametro. 2. Sono ancora un po 'confuso da questa funzione lambda, poiché combinata con la risposta di Kirk Woll, dovrebbe restituire un tipo di modello –

1

Pensate al => dell'operatore nel senso "va a", quindi (m => m) significa "m va a m", un altro modo per dire che si ottiene di nuovo la stessa cosa m.

Nel tuo esempio, @Html.EditorFor(m => m), m è un parametro di input anonima all'espressione lambda m => m, che è un argomento del metodo di estensione EditorFor. Come hai notato nella tua domanda, nessuno degli overload per questo metodo richiede meno di un singolo parametro; questo perché è un Extension Method e il primo parametro indica il tipo che estende. Il secondo parametro è un Expression ed è possibile utilizzare lambda espressioni per questi.

2

1.

  • @Html.EditorFor(m => m) - editor di visualizzazione per intero modello
  • @Html.EditorFor(m => m.propertyName) - editor di display per la proprietà specifica del modello

2.

@Html.EditorFor(m => m) è uguale a @Html.EditorFor(t => t) o @Html.EditorFor(randomName => randomName). Il nome non ha importanza, è solo il nome del parametro. Il tipo per questo parametro è il tipo di modello di vista.

devi passare la funzione, perché non è solo un valore, che conta. Le riflessioni vengono utilizzate per ottenere attributi, che descrivono come visualizzare la proprietà. Guarda questo esempio

public class ResetPasswordModel 
{ 
    public string Username { get; set; } 

    [DataType(DataType.Password)] 
    public string NewPassword { get; set; } 
    [DataType(DataType.Password)] 
    public string PasswordConfirmed { get; set; } 
} 

Gli attributi descrivono che NewPassword deve essere un campo password, non un input regolare. Se passassimo il valore, ciò non sarebbe possibile.

Nel nostro esempio @Html.EditorFor(m => m) mostrerà per contenere un ingresso per il nome utente e la password di due ingressi per le password. @Html.EditorFor(m => m.NewPassword) mostrerà in ingresso, che ha tipo di password.

3.

http://msdn.microsoft.com/en-us/library/ee402949.aspx

public static MvcHtmlString EditorFor<TModel, TValue>(
    this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression 
) 

Questo metodo di estensione per la classe HtmlHelper. this HtmlHelper<TModel> html non è un parametro, è il tipo di classe, tale funzione si estende.