Wie verwende ich knockout.js mit ASP.NET MVC ViewModels?

Kopfgeld

Es ist eine Weile her und ich habe noch ein paar offene Fragen. Ich hoffe, durch das Hinzufügen eines Kopfgeldes werden diese Fragen möglicherweise beantwortet.

Wie benutzt man HTML-Helfer mit knockout.js?

Warum war das Dokument bereit, damit es funktioniert? (Weitere Informationen finden Sie in der ersten Bearbeitung.)

Wie mache ich so etwas, wenn ich das Knockout-Mapping mit meinen Ansichtsmodellen verwende? Da ich aufgrund des Mappings keine Funktion habe.

function AppViewModel() {

    // ... leave firstName, lastName, and fullName unchanged here ...

    this.capitalizeLastName = function() {

    var currentVal = this.lastName();        // Read the current value

    this.lastName(currentVal.toUpperCase()); // Write back a modified value

};

Ich möchte Plugins verwenden. Ich möchte beispielsweise Observables zurücksetzen können, als ob ein Benutzer eine Anfrage storniert. Ich möchte in der Lage sein, zum letzten Wert zurückzukehren. Nach meinen Recherchen scheint dies von Leuten erreicht zu werden, die Plugins wieeditables

Wie verwende ich so etwas, wenn ich Mapping verwende? Ich möchte wirklich nicht zu einer Methode gehen, bei der ich in meiner Ansicht eine manuelle Zuordnung vorgenommen habe, indem ich jedes MVC-ViewMode-Feld einem KO-Modellfeld zuordne, da ich so wenig Inline-Javascript wie möglich haben möchte, und das scheint nur die doppelte Arbeit zu sein, und das ist es warum ich das Mapping mag.

Ich mache mir Sorgen, dass ich viel KO-Power verliere, um diese Arbeit zu vereinfachen (durch die Verwendung von Mapping). Andererseits mache ich mir Sorgen, dass manuelles Mapping nur viel Arbeit bedeutet und meine Ansichten zu viele Informationen und Informationen enthalten wird möglicherweise in Zukunft schwieriger zu warten sein (z. B. wenn ich eine Eigenschaft im MVC-Modell entferne, muss ich sie auch im KO-Ansichtsmodell verschieben)

Ursprünglicher Beitrag

Ich benutze asp.net mvc 3 und sehe mir Knockout an, da es ziemlich cool aussieht, aber es fällt mir schwer, herauszufinden, wie es mit asp.net mvc funktioniert, besonders wenn ich Modelle ansehe.

Für mich mache ich gerade so etwas

 public class CourseVM
    {
        public int CourseId { get; set; }
        [Required(ErrorMessage = "Course name is required")]
        [StringLength(40, ErrorMessage = "Course name cannot be this long.")]
        public string CourseName{ get; set; }


        public List<StudentVm> StudentViewModels { get; set; }

}

Ich hätte eine Vm, die einige grundlegende Eigenschaften wie CourseName hat und eine einfache Validierung darüber haben wird. Das VM-Modell kann bei Bedarf auch andere Ansichtsmodelle enthalten.

Ich würde diese Vm dann an die Ansicht übergeben, wenn ich HTML-Helfer verwenden würde, um sie dem Benutzer anzuzeigen.

@Html.TextBoxFor(x => x.CourseName)

Möglicherweise habe ich einige foreach-Schleifen oder etwas, um die Daten aus der Sammlung von Student View-Modellen abzurufen.

Wenn ich dann das Formular abschicken würde, würde ich jquery und verwendenserialize array und senden Sie es an eine Controller-Aktionsmethode, die es wieder an das Ansichtsmodell bindet.

Mit knockout.js ist alles anders, da Sie jetzt Viewmodels dafür haben und von allen Beispielen, die ich gesehen habe, keine HTML-Helfer verwenden.

Wie nutzen Sie diese 2 Funktionen von MVC mit knockout.js?

ich fandDieses Video In Kürze (in den letzten Minuten des Videos um 18:48 Uhr) wird die Verwendung von Ansichtsmodellen beschrieben, indem im Grunde genommen ein Inline-Skript mit dem Ansichtsmodell knockout.js verwendet wird, dem die Werte im Ansichtsmodell zugewiesen werden.

Ist das der einzige Weg, es zu tun? Wie wäre es in meinem Beispiel mit einer Sammlung von Ansichtsmodellen? Muss ich eine foreach-Schleife oder etwas anderes haben, um alle Werte herauszulösen und sie dem Knockout zuzuweisen?

Was HTML-Helfer betrifft, sagt das Video nichts über sie aus.

Dies sind die beiden Bereiche, die mich verwirren, da nicht viele Leute darüber zu sprechen scheinen und ich verwirrt darüber bin, wie die Anfangswerte und alles auf den Punkt kommen, wenn es sich bei jedem Beispiel um ein hartcodiertes Wertebeispiel handelt.

Bearbeiten

Ich versuche, was Darin Dimitrov vorgeschlagen hat und dies scheint zu funktionieren (ich musste jedoch einige Änderungen an seinem Code vornehmen). Ich bin mir nicht sicher, warum ich document ready verwenden musste, aber irgendwie war ohne das alles nicht fertig.

@model MvcApplication1.Models.Test

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Index</title>
    <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
   <script type="text/javascript">

   $(function()
   {
      var model = @Html.Raw(Json.Encode(Model));


// Activates knockout.js
ko.applyBindings(model);
   });

</script>

</head>
<body>
    <div>
        <p>First name: <strong data-bind="text: FirstName"></strong></p>
        <p>Last name: <strong data-bind="text: LastName"></strong></p>
        @Model.FirstName , @Model.LastName
    </div>
</body>
</html>

Ich musste es um ein JQuery-Dokument wickeln, damit es funktioniert.

Ich bekomme auch diese Warnung. Ich bin nicht sicher, worum es geht.

Warning 1   Conditional compilation is turned off   -> @Html.Raw

Ich habe also einen Ausgangspunkt, den ich zumindest aktualisieren werde, wenn ich ein bisschen mehr herumgespielt habe und wie das funktioniert.

Ich versuche, die interaktiven Tutorials durchzugehen, verwende jedoch stattdessen das ViewModel.

Ich bin noch nicht sicher, wie ich diese Teile angehen soll

function AppViewModel() {
    this.firstName = ko.observable("Bert");
    this.lastName = ko.observable("Bertington");
}

oder

function AppViewModel() {
    // ... leave firstName, lastName, and fullName unchanged here ...

    this.capitalizeLastName = function() {
        var currentVal = this.lastName();        // Read the current value
        this.lastName(currentVal.toUpperCase()); // Write back a modified value
    };

Bearbeiten 2

Ich konnte das erste Problem herausfinden. Keine Ahnung über das zweite Problem. Trotzdem. Hat jemand irgendwelche Ideen?

 @model MvcApplication1.Models.Test

    @{
        Layout = null;
    }

    <!DOCTYPE html>

    <html>
    <head>
        <title>Index</title>
        <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
       <script type="text/javascript">

       $(function()
       {
        var model = @Html.Raw(Json.Encode(Model));
        var viewModel = ko.mapping.fromJS(model);
        ko.applyBindings(viewModel);

       });

    </script>

    </head>
    <body>
        <div>
            @*grab values from the view model directly*@
            <p>First name: <strong data-bind="text: FirstName"></strong></p>
            <p>Last name: <strong data-bind="text: LastName"></strong></p>

            @*grab values from my second view model that I made*@
            <p>SomeOtherValue <strong data-bind="text: Test2.SomeOtherValue"></strong></p>
            <p>Another <strong data-bind="text: Test2.Another"></strong></p>

            @*allow changes to all the values that should be then sync the above values.*@
            <p>First name: <input data-bind="value: FirstName" /></p>
            <p>Last name: <input data-bind="value: LastName" /></p>
            <p>SomeOtherValue <input data-bind="value: Test2.SomeOtherValue" /></p>
            <p>Another <input data-bind="value: Test2.Another" /></p>

           @* seeing if I can do it with p tags and see if they all update.*@
            <p data-bind="foreach: Test3">
                <strong data-bind="text: Test3Value"></strong> 
            </p>

     @*took my 3rd view model that is in a collection and output all values as a textbox*@       
    <table>
        <thead><tr>
            <th>Test3</th>
        </tr></thead>
          <tbody data-bind="foreach: Test3">
            <tr>
                <td>    
                    <strong data-bind="text: Test3Value"></strong> 
<input type="text" data-bind="value: Test3Value"/>
                </td>
            </tr>    
        </tbody>
    </table>

Regler

  public ActionResult Index()
    {
              Test2 test2 = new Test2
        {
            Another = "test",
            SomeOtherValue = "test2"
        };

        Test vm = new Test
        {
            FirstName = "Bob",
            LastName = "N/A",
             Test2 = test2,

        };
        for (int i = 0; i < 10; i++)
        {
            Test3 test3 = new Test3
            {
                Test3Value = i.ToString()
            };

             vm.Test3.Add(test3);
        }

        return View(vm);
    }

Antworten auf die Frage(3)

Ihre Antwort auf die Frage