MVC 3 + KnockoutJS: Hinzufügen des Datenbindungsattributs bei der Verwendung von Editorfor für ein Boolesche Feld

StackOverflow https://stackoverflow.com/questions/7302434

  •  22-10-2019
  •  | 
  •  

Frage

Verwendung @Html.EditorFor(model =>model.IsClient), wo isclient ein Boolescher ist, macht eine Dropdown -Liste mit Not Set, Yes and No als Optionen.

Alles gut und gut.

Jetzt möchte ich KnockoutJs mit der resultierenden Dropdownliste verwenden, die mir gefällt. Wie füge ich das Datenbindungsattribut mit @html.editorFor hinzu, das ich für KnockoutJs mit diesem Dropdown-Unternehmen für die Arbeit benötige?

Ich habe versucht:

@Html.EditorFor(model => model.IsClient, new Dictionary<string, object> { { "data-bind", "value: Account.IsClient" } })

Dies verwendet jedoch den Parameter von Object AdventViewData und macht das Datenbindungsattribut nicht. Das ist wahrscheinlich ganz natürlich, da dieser Parameter wahrscheinlich nichts mit HTML -Attributen für das gerenderte Tag zu tun hat.

Sie können jedoch keine vernünftige Dokumentation finden, und keiner der anderen Überladungen sieht wahrscheinlich Kandidaten für das aus, was ich will.

Tia irgendwelche Vorschläge.

War es hilfreich?

Lösung

Brad Wilson Blogged Über Anzeige- und Editor -Vorlagen in ASP.NET MVC 2. Sie können die Standardvorlage für Booleschen ändern und die benötigten Attribute hinzufügen (Sie benötigen (Sie benötigen (Sie benötigen) (Sie benötigen die Attribute (Sie benötigen (~/Views/Shared/EditorTemplates/MyTemplate.cshtml):

@{
    bool? value = null;
    if (ViewData.Model != null) 
    {
        value = Convert.ToBoolean(ViewData.Model, System.Globalization.CultureInfo.InvariantCulture);
    }

    var triStateValues = new List<SelectListItem> 
    {
        new SelectListItem 
        { 
            Text = "Not Set",
            Value = String.Empty,
            Selected = !value.HasValue 
        },
        new SelectListItem 
        { 
            Text = "True",
            Value = "true",
            Selected = value.HasValue && value.Value 
        },
        new SelectListItem 
        { 
            Text = "False",
            Value = "false",
            Selected = value.HasValue && !value.Value 
        },
    };
}

@if (ViewData.ModelMetadata.IsNullableValueType) 
{
    <!-- TODO: here you can use any attributes you like -->
    @Html.DropDownList(
        "", 
        triStateValues, 
        new { 
            @class = "list-box tri-state", 
            data_bind="value: " + ViewData.TemplateInfo.GetFullHtmlFieldName("") // you could also use ViewData.ModelMetadata.PropertyName if you want to get only the property name and not the entire navigation hierarchy name
        }
    )
} 
else 
{
    @Html.CheckBox("", value ?? false, new { @class = "check-box" })
}

und schlussendlich:

@Html.EditorFor(model => model.IsClient, "MyTemplate")

oder dekorieren Sie die Isclient -Eigenschaft auf Ihrem Ansichtsmodell mit dem UIHint Attribut:

[UIHint("MyTemplate")]
public bool? IsClient { get; set; }

und dann:

 @Html.EditorFor(x => x.IsClient)

Wählt automatisch die benutzerdefinierte Editor -Vorlage aus.

Andere Tipps

Addendum für KnockoutJS -Benutzer:

@Darin Dimitrovs Antwort ist großartig, aber etwas zu starr, um sie mit KnockoutJs zu verwenden, wo komplexe Ansichten zu ViewModels führen können, die nicht vollständig dem @Model -Parameter zugeordnet sind.

Daher habe ich den Parameter von Object assoceViewData verwendet. Um auf den Parameter usonViewData aus Ihrem benutzerdefinierten EditorTemplate zuzugreifen, finden Sie im Folgenden Folgendes:

Greifen Sie über den benutzerdefinierten Code für den benutzerdefinierten EditorTemplate auf zusätzlicheViewData zu

Exkurs: Der zusätzlicheViewData -Param ist dadurch verwirrend, dass er mit dem Standard -Editor nichts unternimmt. Es kommt nur mit einer benutzerdefinierten Editor -Vorlage zur Verfügung.

Wie auch immer, meine Änderungen an Darins Code sind wie folgt:

@if (ViewData.ModelMetadata.IsNullableValueType) 
{
    var x = ViewData["koObservablePrefix"];
    if ((x != "") && (x != null)) { x = x + "."; }
    @Html.DropDownList(
        "", 
        triStateValues, 
        new { 
            @class = "list-box tri-state", 
            data_bind="value: " + x + ViewData.TemplateInfo.GetFullHtmlFieldName("") // or you could also use ViewData.ModelMetadata.PropertyName if you want to get only the property name and not the entire navigation hierarchy name
        }
    )
} 
else 
{
    @Html.CheckBox("", value ?? false, new { @class = "check-box" })
}

Beachten Sie die Zeilen:

var x = ViewData["koObservablePrefix"];
if ((x != "") && (x != null)) { x = x + "."; }

KoobservablePrefix ist vorhanden, damit ich meinem ViewModel Ko.Observable ein willkürliches Präfix hinzufügen kann. Sie könnten andere Dinge tun, wenn Sie dies wählen.

Ich benutze die Variable x wie folgt:

data_bind="value: " + x + ViewData.TemplateInfo.GetFullHtmlFieldName("")

Auf diese Weise, wenn ich nicht in der ontaceViewData "koobservablePrefix" bestehe, funktioniert alles immer noch.

Also kann ich jetzt schreiben:

@Html.EditorFor(model => model.IsClient, "koBoolEditorFor", new { koObservablePrefix = "Account" })

Das wird als:

<select class="list-box tri-state" data-bind="value: Account.IsBank" id="IsBank" name="IsBank">

Beachten Sie das "Wert: Konto.isbank" Datenbindungsattributwert.

Dies ist nützlich, wenn beispielsweise Ihre Ansichten stark eingetippt sind, aber in Ihrem AccountViewModel für Ihre Seite verfügen Sie über eine komplexere Struktur, sodass Sie Ihre Observablen in einem Kontoobjekt verpacken müssen. Z.B:

function account(accountId, personId, accountName, isClient, isProvider, isBank) {

    this.AccountId   = ko.observable(accountId);
    this.PersonId    = ko.observable(personId);
    this.AccountName = ko.observable(accountName);
    this.IsClient    = ko.observable(isClient);
    this.IsProvider  = ko.observable(isProvider);
    this.IsBank      = ko.observable(isBank);
}

function accountViewModel() { 

    var self = this;

    this.selectedCostCentre = ko.observable('');            
    this.Account = new account(@Model.AccountId, @Model.PersonId, '@Model.AccountName', '@Model.IsClient','@Model.IsProvider', '@Model.IsBank');
              // etc. etc
}

Wenn Sie diese Art von Struktur nicht haben, nimmt der Code die Struktur auf. Es geht nur darum, Ihr ViewModel JS auf diese zu maßnen, ähmmm, flexible Konvention.

Hoffe das ist nicht zu verwirrend ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top