@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })
Ich habe eine Variable in meinem Ansichtsdatenwörterbuch namens Readonly. Wie mache ich Menge schreibgeschützt, wenn ViewBag.Readonly wahr ist und nicht gelesen wird, nur wenn es falsch ist?
Einfache Sache, aber die Kombination von Razor mit HTML (das uralt ist) macht ansonsten einfache Dinge unmöglich.
Bearbeitungen:
Ich möchte keine if-Anweisung verwenden. Das ist ein letzter Ausweg, weil es gegen DRY verstößt, was ich in der Vergangenheit viele Male schwer verbrannt habe, weil ich es nicht befolgt habe.
Die Zeile, die ich oben habe, funktioniert insofern, als sie das Textfeld schreibgeschützt macht. Ich muss dies basierend auf meinem Ansichtszustand bedingt machen.
Lösung:
Ich habe folgendes verwendet. Es ist immer noch eine DRY-Verletzung, aber es reduziert es auf eine Zeile.
@Html.EditorFor(model => model.Quantity, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" }} : new { htmlAttributes = new { @class = "form-control" } })
Nett. 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 vorerst.
– Jordanien
20. März 2015 um 18:29 Uhr
Dies ist die beste Antwort
– Benutzer4083514
22. März 2015 um 16:12 Uhr
Das Problem dabei ist, wenn Sie einen großen Satz von haben htmlAttributesmüssen Sie alle anderen wiederholen nur um die readonly zu wechseln??? Und es ist noch schlimmer, wenn Sie andere Attribute (ähnlich wie readonly) unabhängig voneinander zusammenschalten können, z disabled, required… Also angenommen, die Anzahl solcher Attribute ist ndu brauchst 2^n Ausdrücke mit duplizierte Einstellungen für andere Attribute. Das ist ein schreckliches Design. Das beste Design ist in diesem Fall, wenn die Eigenschaft auf gesetzt ist null, ignorieren Sie einfach das Rendern. ASP.NET MVC muss noch weiter verbessert werden.
– König König
8. Juni 2017 um 1:50 Uhr
Dunkelsiegel
Heute musste ich mich mit diesem Problem befassen, da ich ein “schreibgeschütztes” Attribut dynamisch auf a setzen musste Html.TextBoxFor Element. Am Ende schrieb ich die folgende Hilfsmethode, die es mir ermöglichte, das Problem zu umgehen, während ich einen DRY-Ansatz beibehielt:
/// <summary>
/// Gets an object containing a htmlAttributes collection for any Razor HTML helper component,
/// supporting a static set (anonymous object) and/or a dynamic set (Dictionary)
/// </summary>
/// <param name="fixedHtmlAttributes">A fixed set of htmlAttributes (anonymous object)</param>
/// <param name="dynamicHtmlAttributes">A dynamic set of htmlAttributes (Dictionary)</param>
/// <returns>A collection of htmlAttributes including a merge of the given set(s)</returns>
public static IDictionary<string, object> GetHtmlAttributes(
object fixedHtmlAttributes = null,
IDictionary<string, object> dynamicHtmlAttributes = null
)
{
var rvd = (fixedHtmlAttributes == null)
? new RouteValueDictionary()
: HtmlHelper.AnonymousObjectToHtmlAttributes(fixedHtmlAttributes);
if (dynamicHtmlAttributes != null)
{
foreach (KeyValuePair<string, object> kvp in dynamicHtmlAttributes)
rvd[kvp.Key] = kvp.Value;
}
return rvd;
}
Es kann auf folgende Weise verwendet werden:
var dic = new Dictionary<string,object>();
if (IsReadOnly()) dic.Add("readonly", "readonly");
Html.TextBoxFor(m => m.Name, GetHtmlAttributes(new { @class="someclass" }, dic))
Der Code ist ziemlich selbsterklärend, aber ich habe auch die zugrunde liegende Logik in erklärt dieser Beitrag auf meinem Blog.
Immer noch ziemlich hässlicher Rasiercode, aber ich kann damit arbeiten. Danke, Anstelle eines Wörterbuchs würde ich wahrscheinlich eine Übersetzungsschicht erstellen, die sich ändern würde readonly=true zu readonly="readonly" und entfernen readonly=false sodass read-only auf einen booleschen Wert gesetzt werden kann. Dumme HTML-Spezifikation mit deinen wertlosen Attributen! Deshalb normalisieren wir Schnittstellen. Ich wünschte, ich könnte die Zeit zurückdrehen und manchmal jemanden schlagen.
– Jordanien
14. November 2018 um 16:16 Uhr
@Jordan , der Hauptvorteil dieser Problemumgehung besteht darin, dass sie auch verwendet werden kann, um andere Eigenschaftseinstellungen und / oder bewertete Attribute (einschließlich, aber nicht beschränkt auf, schreibgeschützt) dynamisch festzulegen.
– Dunkelsiegel
14. November 2018 um 17:38 Uhr
Richtig, aber das Problem mit dem OP war mit wertlosen Attributen, die eher klein sind. Die einzigen, die mir einfallen, sind readonly und disabled. Dies sind die einzigen wirklichen Probleme, wenn Sie darüber nachdenken. Sie sind die einzigen Attribute, die Sie nicht einfach leer lassen können.
– Jordanien
14. November 2018 um 20:04 Uhr
ataravati
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" } })
}
Sie können HTML-Attribute an übergeben Html.EditorFor in MVC5 (Ich hätte klarer sein sollen, welche Version von MVC ich verwende.) Der Code, den ich oben habe, macht das Textfeld schreibgeschützt. Ich weiß nicht, wie ich das ohne eine if-Anweisung bedingt machen soll (wieder hätte klarer sein sollen, sorry).
– Jordanien
19. März 2015 um 19:32 Uhr
Warum willst du nicht ein verwenden if Aussage?
– ataravati
19. März 2015 um 19:34 Uhr
Kein Problem. Ich habe mich in der Vergangenheit verbrannt, weil ich das DRY-Prinzip nicht befolgt habe. Eine einzige zweiteilige if-Anweisung mit sehr einfachem Inhalt scheint keine große Sache zu sein, aber sie kann wachsen, wenn Sie den Code im Laufe der Zeit ändern. Ich werde dies tun, wenn sich keine andere Lösung bietet, aber das scheint nur eine Schwäche im Fleck zu sein, dies nicht tun zu können. HTML sollte readonly=’true|false’ verwenden, nicht diesen Nur-Namen-Attribut-Unsinn, den sie immer noch haben.
– Jordanien
19. März 2015 um 19:37 Uhr
Und es ist WIRKLICH hässlicher Code, if-Anweisungen überall dort zu haben, wo Sie etwas so Einfaches tun möchten, wie ein Feld bedingt schreibgeschützt zu machen. Ich mag es, wenn mein Code für Menschen lesbar ist. Ich kann sehen, ob ich die Integer-Vorlage hacken und dies selbst tun kann, um diese Situation zu vermeiden. Ich muss herausfinden, wie das geht. …
– Jordanien
19. März 2015 um 19:39 Uhr
Ich stimme zu, dass es hässlich ist. Aber es gibt keine andere Möglichkeit. Es sei denn, Sie möchten AngularJS verwenden, was meiner Meinung nach völlig unnötig ist, wenn Sie es nur für diesen Zweck verwenden möchten.
– ataravati
19. März 2015 um 19:42 Uhr
Falls Sie viele Orte mit einer solchen Logik sehen, denke ich, die Bibliothek zu verwenden FluentDataAnnotations kann Ihren Code sauber und klar halten.
Wenn Sie sich auskennen FluentValidatores ist sehr ähnlich mit.
In Ihrem Fall wird die gesamte Logik von einer Ansicht in eine Modellanmerkungsklasse verschoben. In werden Sie nur haben @Html.EditorFor(model => model.Quantity)
Es erlaubt sogar, Modelleigenschaften in Bedingungen zu verwenden, z this.When(model => !model.AllowEditPhone,
() => {
this.For(m => m.Phone).SetReadOnly(false);
});
Hier die NuGet-Paket dafür ist ASP.NET MVC 5 erforderlich. (Unterstützung für ASP.NET Core ist in Arbeit.)
Durch das Schreiben einer Hilfsmethode kann das DRY-Prinzip respektiert werden.