2015-03-19 9 views
8

Ich habe diese Zeile Code:Wie mache ich EditorFor bedingt schreibgeschützt?

@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } }) 

Ich habe eine Variable aus meiner Sicht Data Dictionary Read-Only genannt. Wie mache ich die Menge schreibgeschützt, wenn ViewBag.Readonly wahr ist und nicht nur gelesen wird, wenn sie falsch ist?

Einfache Sache, aber die Kombination von Razor mit HTML (die alt ist) macht sonst einfache Dinge unmöglich.

Edits:

Ich will nicht eine if-Anweisung verwenden. Das ist ein letzter Ausweg, weil es gegen DRY verstößt, wo ich in der Vergangenheit schon mehrmals schwer verbrannt wurde, weil ich nicht gefolgt bin.

Die Zeile, die ich oben habe, funktioniert insofern, als sie das Textfeld schreibgeschützt macht. Ich muss dies abhängig von meinem Ansichtszustand machen.

Lösung:

ich folgendes benutzt habe. Es ist immer noch eine DRY-Verletzung, aber es reduziert es auf eine Zeile.

@Html.EditorFor(model => model.Quantity, new { htmlAttributes = ViewBag.Readonly ? (object)new { @class = "form-control", @readonly = "htmlsucks" } : (object)new { @class = "form-control" } }) 

Antwort

15

EDIT: MVC 5

-Controller

ViewBag.Readonly=true;//false 

Ansicht

@Html.EditorFor(model => model.Quantity, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" }} : new { htmlAttributes = new { @class = "form-control" } }) 
+0

Schön. Ich sehe, wie Sie die DRY-Verletzung minimiert haben. Ich respektiere das. Ich habe die Dinge ein wenig geändert, aber ich denke, ich werde das verwenden. Ich hoffe immer noch auf bessere Optionen, aber das funktioniert jetzt. – Jordan

+1

Dies ist die beste Antwort –

+2

das Problem ist, wenn Sie eine große Menge von 'htmlAttributes' haben, müssen Sie alle anderen *** wiederholen, nur um die readonly *** ??? Und es ist noch schlimmer, wenn Sie andere Attribute (ähnlich wie nur gelesen) haben, um unabhängig voneinander zu wechseln, wie zum Beispiel "deaktiviert", "erforderlich", ... Nehmen Sie an, die Anzahl solcher Attribute ist "n", Sie brauchen "2^n Ausdrücke mit *** duplizierten Einstellungen *** für andere Attribute. Das ist ein schreckliches Design. Das beste Design in diesem Fall ist, wenn die Eigenschaft auf 'null' gesetzt ist, ignorieren Sie einfach das Rendering. ASP.NET MVC benötigt noch mehr Verbesserung. –

3

Es ist sehr einfach. Mach es so.

@if((bool)ViewBag.Readonly) 
{ 
    @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } }) 
} 
else 
{ 
    @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } }) 
} 
+0

Sie können HTML-Attribut übergeben es zu 'Html.EditorFor' in MVC5 (Ich hätte besser wissen sollen, welche Version von MVC ich verwende.) Der Code, den ich oben habe, macht das Textfeld nur lesbar. Ich weiß nicht, wie ich das ohne eine if-Anweisung konditionieren soll (sollte nochmal klarer sein, sorry). – Jordan

+0

Entschuldigung! Du hast recht. Ich habe meine Antwort aktualisiert. – ataravati

+0

Warum möchten Sie nicht eine 'if' Anweisung verwenden? – ataravati

0

Durch eine Hilfsmethode Schreiben des DRY Principal kann respektiert werden.

using System.Web.Mvc.Html; 

    public static MvcHtmlString Concat(this MvcHtmlString first, params MvcHtmlString[] strings) 
    { 
     return MvcHtmlString.Create(first.ToString() + string.Concat(strings.Select(s => (s == null ? "" : s.ToString())))); 
    } 

    public static MvcHtmlString ConditionalEditFor<TModel,TValue>(this HtmlHelper<TModel> helper, bool EditCondition, Expression<Func<TModel, TValue>> Expression) 
    { 
     helper.ConditionalEditFor(EditCondition,Expression,false); 
    } 

    public static MvcHtmlString ConditionalEditFor<TModel, TValue>(this HtmlHelper<TModel> helper, bool EditCondition, Expression<Func<TModel, TValue>> Expression, bool IncludeValidationOnEdit) 
    { 
     if (EditCondition) 
     { 
      if (!IncludeValidationOnEdit) 
       return EditorExtensions.EditorFor<TModel, TValue>(helper, Expression); 
      else 
       return EditorExtensions.EditorFor<TModel, TValue>(helper, Expression).Concat(ValidationExtensions.ValidationMessageFor<TModel, TValue>(helper, Expression)); 
     } 
     else 
     { 
      return DisplayExtensions.DisplayFor<TModel, TValue>(helper, Expression); 
     } 
    } 

dann in der Ansicht:

eine bedingte Anweisung hinzufügen Nur-Lese- zum Beispiel um zu bestimmen,

@{bool IsReadOnly = YourCondition;} 

@Html.ConditionalEditFor(!IsReadOnly/*condition*/, model => model.YourProperty,true /*do validation*/) 

Sie können dann alle anderen gewünschten Überschreibungen hinzufügen.

1

Wenn Sie viele Orte in Ihrer Ansicht mit solcher Logik haben, denke ich, mit der Bibliothek FluentDataAnnotations können Sie Code sauber und klar halten.

Wenn Sie vertraut sind mit FluentValidator, es ist sehr ähnlich mit.

In Ihrem Fall wird die gesamte Logik von einer Ansicht in die Annotationsklasse des Modells verschoben. In Sie werden nur @Html.EditorFor(model => model.Quantity)

Es ermöglicht sogar Modelleigenschaften unter Bedingungen z. this.When(model => !model.AllowEditPhone, () => { this.For(m => m.Phone).SetReadOnly(false); });

Hier ist die NuGet package, die (für ASP.NET Core sind im Gange. Support)

0

JQUERY lesen SETUP_TYPE Steuerwert und deaktivieren Kontrollen mit einem bestimmten CSS-Selektor ASP.NET MVC 5. erfordert.

$(function() { 
    if ($("#SETUP_TYPE").val() == "1") { $('.XXX').attr('disabled', true); } 
}) 

$(function() { 
    if ($("#SETUP_TYPE").val() == "2") { $('.YYY').attr('disabled', true); } 
}) 

Diese Steuerung wird deaktiviert, wenn SETUP_TYPE 1 oder 2.

@Html.EditorFor(model => model.CLAIM, new { htmlAttributes = new { @class = "form-control XXX YYY" } }) 

Diese Steuerung wird deaktiviert, wenn SETUP_TYPE 1.

@Html.EditorFor(model => model.POLICY, new { htmlAttributes = new { @class = "form-control XXX" } }) 

wird diese Steuerung wird deaktiviert, wenn SETUP_TYPE 2 ist.

@Html.EditorFor(model => model.INSURED, new { htmlAttributes = new { @class = "form-control YYY" } }) 
Verwandte Themen