Kopfgeld
Es ist eine Weile her und ich habe noch ein paar offene Fragen. Ich hoffe, dass diese Fragen durch Hinzufügen eines Kopfgeldes beantwortet werden.
- Wie benutzt man HTML-Helfer mit knockout.js?
Warum war das Dokument bereit, damit es funktioniert? (Weitere Informationen finden Sie unter Erste Bearbeitung.)
Wie mache ich so etwas, wenn ich das Knockout-Mapping mit meinen Ansichtsmodellen verwende? Da ich aufgrund der Zuordnung 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, zum Beispiel möchte ich Observables zurücksetzen können, als ob ein Benutzer eine Anfrage stornieren möchte, um zum letzten Wert zurückkehren zu können. Aus meiner Forschung geht hervor, dass dies durch Leute erreicht wird, die Plugins wie editierbare Dateien erstellen
Wie verwende ich so etwas, wenn ich Mapping verwende? Ich möchte wirklich nicht zu einer Methode gehen, bei der ich in meiner Ansicht ein manuelles Mapping habe, bei dem ich jedes MVC viewMode-Feld einem KO-Modellfeld zuordne, da ich so wenig Inline-Javascript wie möglich möchte, und das scheint nur doppelt so viel Arbeit zu sein warum ich dieses Mapping mag.
Ich mache mir Sorgen, dass ich, um diese Arbeit zu vereinfachen (durch die Verwendung von Mapping), viel KO-Leistung verlieren werde, aber andererseits mache ich mir Sorgen, dass manuelles Mapping nur viel Arbeit bedeutet und meine Ansichten zu viele Informationen und Informationen enthalten Möglicherweise wird die Wartung in Zukunft schwieriger (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 schaue mir Knockout an, da es ziemlich cool aussieht, aber es fällt mir schwer herauszufinden, wie es mit asp.net mvc funktioniert, insbesondere mit Ansichtsmodellen.
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 darüber hinaus eine einfache Validierung hat. 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 zu entfernen.
Wenn ich dann das Formular abschicke, verwende ich jquery und serialize array
sende es an eine Controller-Aktionsmethode, die es wieder an das Ansichtsmodell bindet.
Mit knockout.js ist alles anders, da Sie jetzt Ansichtsmodelle dafür haben und aus all den Beispielen, die ich gesehen habe, keine HTML-Helfer verwenden.
Wie verwenden Sie diese beiden Funktionen von MVC mit knockout.js?
Ich habe dieses Video gefunden und es geht kurz (letzte Minuten des Videos um 18:48 Uhr) in die Verwendung von Ansichtsmodellen ein, indem im Grunde ein Inline-Skript mit dem Ansichtsmodell knockout.js verwendet wird, dem die Werte im ViewModel zugewiesen werden.
Ist dies der einzige Weg, dies 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 zu extrahieren und sie in 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 zur Ansicht gelangen, wenn ein Beispiel nur ein hartcodiertes Wertebeispiel ist.
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 das Dokument fertig verwenden musste, aber irgendwie war nicht alles ohne es 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 Abfragedokument wickeln, damit es funktioniert.
Ich bekomme auch diese Warnung. Ich bin mir 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 noch ein bisschen herumgespielt habe und wie das funktioniert.
Ich versuche, die interaktiven Tutorials durchzugehen, verwende aber stattdessen ein ViewModel.
Ich bin mir 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 vom zweiten 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:
Ich glaube, ich habe alle Ihre Fragen zusammengefasst. Wenn ich etwas verpasst habe, lassen Sie es mich bitte wissen ( Wenn Sie alle Ihre Fragen an einem Ort zusammenfassen könnten, wäre das schön =).
Hinweis. Kompatibilität mit dem
ko.editable
hinzugefügten Plug-InLaden Sie den vollständigen Code herunter
Wie benutzt man HTML-Helfer mit knockout.js?
Das ist einfach:
Wo:
value: CourseId
Gibt an, dass Sie dievalue
Eigenschaft desinput
Steuerelements mit derCourseId
Eigenschaft Ihres Modells und Ihres Skriptmodells verbindenDas Ergebnis ist:
Warum war das Dokument bereit, damit es funktioniert? (Weitere Informationen finden Sie unter Erste Bearbeitung.)
Ich verstehe noch nicht, warum Sie das
ready
Ereignis verwenden müssen, um das Modell zu serialisieren, aber es scheint, dass es einfach erforderlich ist (keine Sorge)Wie mache ich so etwas, wenn ich das Knockout-Mapping mit meinen Ansichtsmodellen verwende? Da ich aufgrund der Zuordnung keine Funktion habe.
Wenn ich das richtig verstehe, müssen Sie eine neue Methode an das KO-Modell anhängen. Das ist einfach, Modelle zusammenzuführen
Weitere Informationen finden Sie im Abschnitt - Zuordnung aus verschiedenen Quellen -
Über die Warnung, die Sie erhalten haben
Sie müssen Anführungszeichen verwenden
Kompatibilität mit dem Plug-In ko.editable
Ich dachte, es würde komplexer werden, aber es stellt sich heraus, dass die Integration wirklich einfach ist. Um Ihr Modell bearbeitbar zu machen, fügen Sie einfach die folgende Zeile hinzu: (Denken Sie daran, dass ich in diesem Fall ein gemischtes Modell von Server und verwende Das Hinzufügen einer Erweiterung im Client und das Bearbeiten funktioniert einfach ... es ist großartig):
Von hier aus müssen Sie nur spielen mit den zusätzlichen Erweiterungen mit Bindungen durch die Plug-in, zum Beispiel, habe ich eine Schaltfläche wie diese Bearbeitung meine Felder zu starten und in dieser Taste I um den Bearbeitungsvorgang zu starten:
Dann habe ich Commit- und Cancel-Buttons mit folgendem Code:
Und schließlich habe ich ein Feld, das angibt, ob sich die Felder im Bearbeitungsmodus befinden oder nicht. Dies dient nur zum Binden der enable-Eigenschaft.
Über Ihre Array-Frage
Sie können dasselbe mit KO tun. Im folgenden Beispiel werde ich die folgende Ausgabe erstellen:
Grundsätzlich haben Sie hier zwei Listen, die
Helpers
mit KO erstellt und mit KO verbunden wurden. Sie haben eindblClick
Ereignis gebunden, das beim Auslösen das ausgewählte Element aus der aktuellen Liste entfernt und zur anderen Liste hinzufügt, wenn Sie in die Liste postenController
den Inhalt der einzelnen Die Liste wird als JSON-Daten gesendet und erneut an das Servermodell angehängtNuggets:
Externe Skripte .
Controller-Code
Modell
CSHTML-Seite
Skripte
Hinweis: Ich habe gerade diese Zeilen hinzugefügt:
Da beim Senden des Formulars meine Felder deaktiviert sind und die Werte nicht an den Server übertragen wurden, habe ich einige versteckte Felder hinzugefügt, um den Trick auszuführen
quelle
ko.editables
Plug-In hinzugefügt. Sie können die aktualisierte Antwort überprüfen oder, wenn Sie möchten, das gesamte Projekt herunterladen, um es lokalSie können Ihr ASP.NET MVC-Ansichtsmodell in eine Javascript-Variable serialisieren:
In der Knockout-Dokumentation finden Sie viele Beispiele , die Sie durchgehen könnten.
quelle
Um die zusätzlichen berechneten Eigenschaften nach der Serverzuordnung zu erreichen, müssen Sie Ihre Ansichtsmodelle auf der Clientseite weiter verbessern.
Beispielsweise:
Jedes Mal, wenn Sie aus unformatiertem JSON zuordnen, müssen Sie die berechneten Eigenschaften erneut anwenden.
Darüber hinaus bietet das Mapping-Plugin die Möglichkeit, ein Ansichtsmodell schrittweise zu aktualisieren, anstatt es jedes Mal neu zu erstellen, wenn Sie hin und her gehen (verwenden Sie einen zusätzlichen Parameter in
fromJS
):Dadurch wird eine inkrementelle Datenaktualisierung Ihres Modells nur von Eigenschaften ausgeführt, die zugeordnet sind. Weitere Informationen hierzu finden Sie in der Mapping-Dokumentation
Sie haben in den Kommentaren zu Darins Antwort das FluentJSON- Paket erwähnt. Ich bin der Autor davon, aber sein Anwendungsfall ist spezifischer als ko.mapping. Ich würde es im Allgemeinen nur verwenden, wenn Ihre Ansichtsmodelle eine Möglichkeit sind (z. B. Server -> Client) und die Daten dann in einem anderen Format (oder überhaupt nicht) zurückgesendet werden. Oder wenn Ihr Javascript-Ansichtsmodell in einem wesentlich anderen Format als Ihr Servermodell vorliegen muss.
quelle