KnockoutJS - Kurzanleitung

KnockoutJS ist im Grunde eine in JavaScript geschriebene Bibliothek, die auf MVVM-Mustern basiert und Entwicklern hilft, umfangreiche und reaktionsschnelle Websites zu erstellen. Das Modell trennt das Modell der Anwendung (gespeicherte Daten), die Ansicht (Benutzeroberfläche) und das Ansichtsmodell (JavaScript-Darstellung des Modells).

KnockoutJS wurde entwickelt und wird am 5. Juli 2010 von Steve Sanderson, einem Microsoft-Mitarbeiter, als Open-Source-Projekt gepflegt. KO ist eine Abkürzung für KnockoutJS. KO unterstützt alle gängigen Browser - IE 6+, Firefox 3.5+, Chrome, Opera, Safari (Desktop / Mobile).

Eigenschaften von KnockoutJS

Hier ist eine Liste der wichtigsten Funktionen von KnockoutJS -

  • Declarative Binding- HTML-DOM-Elemente werden über ein Datenbindungsattribut mit einer sehr einfachen Syntax mit dem Modell verbunden. Mit dieser Funktion ist es einfach, eine Reaktionsfähigkeit zu erreichen.

  • Automatic UI Refresh- Alle Änderungen, die zum Anzeigen der Modelldaten vorgenommen werden, werden automatisch in der Benutzeroberfläche angezeigt und umgekehrt. Sie müssen keinen zusätzlichen Code schreiben.

  • Dependency Tracking- Die Beziehung zwischen KO-Attributen und KO-Bibliotheksfunktionen / -komponenten ist transparent. Verfolgt automatisch Datenänderungen im KO-Attribut und aktualisiert die jeweiligen betroffenen Bereiche.

  • Templating - Vorlagen sind eine einfache und bequeme Möglichkeit, komplexe UI-Strukturen - mit der Möglichkeit, Blöcke zu wiederholen oder zu verschachteln - als Funktion von Ansichtsmodelldaten zu erstellen.

  • Extensible - Erweitert das benutzerdefinierte Verhalten sehr einfach.

Warum KnockoutJS verwenden?

  • Die KnockoutJS-Bibliothek bietet eine einfache und saubere Möglichkeit, komplexe datengesteuerte Schnittstellen zu verwalten. Man kann selbstaktualisierende Benutzeroberflächen für Javascript-Objekte erstellen.

  • Es ist eine reine JavaScript-Bibliothek und funktioniert mit jedem Webframework. Es ist kein Ersatz für JQuery, kann aber als Ergänzung mit intelligenten Funktionen dienen.

  • Die KnockoutJS-Bibliotheksdatei ist sehr klein und leicht.

  • KnockoutJS ist unabhängig von anderen Frameworks. Es ist mit anderen clientseitigen oder serverseitigen Technologien kompatibel.

  • Am wichtigsten ist, dass KnockoutJS Open Source ist und daher kostenlos verwendet werden kann.

  • KnockoutJS ist vollständig dokumentiert. Die offizielle Website enthält eine vollständige Dokumentation mit API-Dokumenten, Live-Beispielen und interaktiven Tutorials.

Es ist sehr einfach, KnockoutJS zu verwenden. Verweisen Sie einfach auf die JavaScript-Datei mit dem <script> -Tag in HTML-Seiten.

Auf Knockout.js kann auf folgende Arten zugegriffen werden:

  • Sie können die Produktionsversion von Knockout.js von der offiziellen Website herunterladen

    Eine Seite wie im folgenden Bild wird angezeigt. Klicken Sie auf den Download-Link und Sie erhalten die neueste Datei knockout.js.

Verweisen Sie nun auf die Datei wie im folgenden Code gezeigt.

<script type = 'text/javascript' src = 'knockout-3.3.0.js'></script>

Aktualisieren Sie das src-Attribut so, dass es dem Speicherort entspricht, an dem die heruntergeladenen Dateien gespeichert werden.

  • Sie können von CDNs auf die KnockoutJS-Bibliothek verweisen -

    • Sie können die KnockoutJS-Bibliothek von Microsoft Ajax CDN in Ihrem Code wie folgt referenzieren :

<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
   type = "text/javascript"></script>
  • Alternativ können Sie auf eine verkleinerte Version der KnockoutJS-Bibliothek von CDNJS wie folgt verweisen :

<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js" 
   type = "text/javascript"></script>

Note - In allen Kapiteln dieses Tutorials haben wir auf die CDN-Version der KnockoutJS-Bibliothek verwiesen.

Beispiel

KnockoutJS basiert auf dem MVVM-Muster (Model-View-ViewModel). Wir werden dieses Muster im Kapitel KnockoutJS - MVVM Framework eingehend untersuchen . Schauen wir uns zunächst ein einfaches Beispiel für KnockoutJS an.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Simple Example</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
         type = "text/javascript"></script>
   </head>

   <body>
      <!-- This is called "view" of HTML markup that defines the appearance of UI -->

      <p>First String: <input data-bind = "value: firstString" /></p>
      <p>Second String: <input data-bind = "value: secondString" /></p>

      <p>First String: <strong data-bind = "text: firstString">Hi</strong></p>
      <p>Second String: <strong data-bind = "text: secondString">There</strong></p>

      <p>Derived String: <strong data-bind = "text: thirdString"></strong></p>

      <script>
         <!-- This is called "viewmodel". This javascript section defines the data and 
            behavior of UI -->

         function AppViewModel() {
            this.firstString = ko.observable("Enter First String");
            this.secondString = ko.observable("Enter Second String");

            this.thirdString = ko.computed(function() {
               return this.firstString() + " " + this.secondString();
            }, this);
         }

         // Activates knockout.js
         ko.applyBindings(new AppViewModel());
      </script>

   </body>
</html>

Die folgende Zeile bezieht sich auf die KnockoutJS-Bibliothek.

<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
   type = "text/javascript"> </script>

Diese Zeile verweist auf die KnockoutJS-Bibliothek.

Wir haben zwei Eingabefelder: First String und Second String. Diese beiden Variablen werden in ViewModel mit den Werten Enter First String und Enter Second String initialisiert.

<p>First String: < input data-bind = "value: firstString" /> </p>

Auf diese Weise binden wir Werte aus ViewModel mit HTML-Elementen 'data-bind' Attribut im Body-Bereich.

Hier bezieht sich 'firstString' auf die ViewModel-Variable.

this.firstString = ko.observable("Enter First String");

ko.observable ist ein Konzept, das die Wertänderungen im Auge behält, damit die zugrunde liegenden ViewModel-Daten aktualisiert werden können.

Um dies besser zu verstehen, aktualisieren wir das erste Eingabefeld auf "Hallo" und das zweite Eingabefeld auf "TutorialsPoint". Sie werden sehen, dass die Werte gleichzeitig aktualisiert werden. Wir werden mehr über dieses Konzept im Kapitel KnockoutJS - Observables lernen .

this.thirdString = ko.computed(function() {
   return this.firstString() + " " + this.secondString();
}, this);

Als nächstes haben wir die Funktion im Ansichtsmodell berechnet. Diese Funktion leitet die dritte Zeichenfolge basierend auf 2 zuvor erwähnten Zeichenfolgen ab. Daher werden alle an diesen Zeichenfolgen vorgenommenen Aktualisierungen automatisch in dieser abgeleiteten Zeichenfolge wiedergegeben. Es ist nicht erforderlich, einen zusätzlichen Code zu schreiben, um dies zu erreichen. Dies ist nur ein einfaches Beispiel. Wir werden dieses Konzept im Kapitel KnockoutJS - Computed Observables untersuchen .

Ausgabe

Speichern Sie den obigen Code als my_first_knockoutjs_program.html. Öffnen Sie diese Datei in Ihrem Browser und Sie sehen eine Ausgabe wie folgt.

Ändern Sie die Zeichenfolgen in "Hallo" und "TutorialsPoint", und die Ausgabe ändert sich wie folgt.

KnockoutJS wird häufig für Einzelseitenanwendungen verwendet - Eine Website, die mit der Fähigkeit erstellt wurde, alle erforderlichen Daten dynamisch mit einer einzigen Seitenlast abzurufen, wodurch Server-Roundtrips reduziert werden.

KnockoutJS ist ein clientseitiges Framework. Dies ist eine JavaScript-Bibliothek, mit der HTML sehr einfach an Domänendaten gebunden werden kann. Es implementiert ein Muster namens Model-View-ViewModel (MVVM). Observables ist die magische Zutat von KnockoutJS. Alle Daten bleiben aufgrund des Observable-Attributs synchron.

Die Architektur

Aussicht

Ansicht ist nichts anderes als eine Benutzeroberfläche, die mit HTML-Elementen und CSS-Stil erstellt wurde.

Sie können HTML-DOM-Elemente mit KnockoutJS an das Datenmodell binden. Es bietet eine bidirektionale Datenbindung zwischen View und ViewModel mithilfe des Datenbindungskonzepts. Dies bedeutet, dass alle in der Benutzeroberfläche vorgenommenen Aktualisierungen im Datenmodell und alle im Datenmodell vorgenommenen Änderungen in der Benutzeroberfläche wiedergegeben werden. Mit Hilfe von knockoutJS kann eine selbstaktualisierende Benutzeroberfläche erstellt werden.

ViewModel

ViewModel ist ein JavaScript-Objekt, das die erforderlichen Eigenschaften und Funktionen zur Darstellung von Daten enthält. View und ViewModel sind mit dem in HTML verwendeten deklarativen Datenbindungskonzept verbunden. Dies macht es einfach, HTML zu ändern, ohne ViewModel zu ändern. KnockoutJS sorgt für die automatische Datenaktualisierung zwischen ihnen mithilfe von Observables.

Die Synchronisation von Daten wird durch Binden von DOM-Elementen an das Datenmodell erreicht, wobei zuerst die Datenbindung verwendet und diese beiden Komponenten dann mithilfe von Observables aktualisiert werden. Aufgrund dieser Synchronisation der Daten erfolgt die Abhängigkeitsverfolgung automatisch. Es ist keine zusätzliche Codierung erforderlich, um dies zu erreichen. Mit KnockoutJS kann eine direkte Verbindung zwischen der Anzeige und den zugrunde liegenden Daten hergestellt werden.

Sie können eigene Bindungen erstellen, die als benutzerdefinierte Bindungen für anwendungsspezifische Verhaltensweisen bezeichnet werden. Auf diese Weise können Sie mit Knockout direkt steuern, wie Sie Ihre Daten in HTML umwandeln möchten.

Modell

Modell sind die Domänendaten auf dem Server und werden bearbeitet, sobald die Anforderung von ViewModel gesendet / empfangen wird.

Die Daten können in einer Datenbank, einem Cookie oder einer anderen Form der dauerhaften Speicherung gespeichert werden. KnockoutJS macht sich keine Sorgen darüber, wie es gespeichert wird. Es ist Sache des Programmierers, zwischen den gespeicherten Daten und KnockoutJS zu kommunizieren.

In den meisten Fällen werden Daten über einen Ajax-Aufruf gespeichert und geladen.

Model-View-ViewModel (MVVM)ist ein architektonisches Entwurfsmuster für die Entwicklung von Softwareanwendungen. MVVM wurde 2005 von Microsoft Architect John Gossman entwickelt. Dieses Muster leitet sich vom MVC-Muster (Model-View-Controller) ab. Der Vorteil von MVVM besteht darin, dass die grafische Benutzeroberfläche der Anwendungsschicht von der Geschäftslogik getrennt wird. MVVM ist dafür verantwortlich, Daten aus dem zugrunde liegenden Modell so zu behandeln, dass sie sehr einfach dargestellt und verwaltet werden. ViewModel in MVVM repräsentiert eine abstrakte Version des Status und der Aktionen von View.

Die Ansichtsklassen wissen nicht, dass Model- und ViewModel-Klassen vorhanden sind, und Model und ViewModel wissen nicht, dass View vorhanden ist. Model ist auch nicht bekannt, dass ViewModel und View vorhanden sind.

Die Architektur

Aussicht

View ist eine grafische Benutzeroberfläche, die mithilfe der Auszeichnungssprache zur Darstellung von Daten erstellt wurde. View bindet über das Datenbindungskonzept, das indirekt eine Verbindung zu den Modelldaten herstellt, an Eigenschaften eines ViewModel. Die Ansicht muss für Änderungen in ViewModel nicht geändert werden. Änderungen an Daten in ViewModel werden aufgrund von Bindungen automatisch in View weitergegeben.

Modell

Modell sind Domänendaten oder Geschäftsobjekte, die Echtzeitdaten enthalten. Modell trägt kein Verhalten. Verhalten wird meist in der Geschäftslogik implementiert.

ViewModel

ViewModel ist der zentrale Ort, an dem Daten aus der Anzeigelogik von Model und View gebündelt werden. ViewModel enthält den dynamischen Status von Daten. Zwischen View und ViewModel befindet sich ein impliziter Ordner, um miteinander zu kommunizieren. Diese Bindung beinhaltet deklarative Daten und Befehlsbindung. Die Synchronisation von View und ViewModel wird durch diese Bindung erreicht. Jede in View vorgenommene Änderung wird in ViewModel wiedergegeben, und jede Änderung in ViewModel wird automatisch in View wiedergegeben. Das Vorhandensein dieses 2-Wege-Bindungsmechanismus ist ein Schlüsselaspekt dieses MVVM-Musters.

KnockoutJS baut auf den folgenden 3 wichtigen Konzepten auf.

  • Observables und Abhängigkeitsverfolgung zwischen ihnen - DOM-Elemente werden über 'Datenbindung' mit ViewModel verbunden. Sie tauschen Informationen über Observables aus. Dies sorgt automatisch für die Abhängigkeitsverfolgung.

  • Deklarative Bindungen zwischen Benutzeroberfläche und ViewModel - DOM-Elemente werden über das Datenbindungskonzept mit ViewModel verbunden.

  • Vorlagen zum Erstellen wiederverwendbarer Komponenten - Vorlagen bieten eine robuste Möglichkeit zum Erstellen komplexer Webanwendungen.

Wir werden Observables in diesem Kapitel untersuchen.

Wie der Name schon sagt, werden beim Deklarieren von ViewModel-Daten / -Eigenschaften als beobachtbar Datenänderungen jedes Mal automatisch an allen Stellen wiedergegeben, an denen die Daten verwendet werden. Dies umfasst auch das Aktualisieren der zugehörigen Abhängigkeiten. KO kümmert sich um diese Dinge und es ist nicht erforderlich, zusätzlichen Code zu schreiben, um dies zu erreichen.

Mit Observable wird es sehr einfach, UI und ViewModel dynamisch miteinander zu kommunizieren.

Syntax

Sie müssen nur die ViewModel-Eigenschaft mit Funktion deklarieren ko.observable() um es beobachtbar zu machen.

this.property = ko.observable('value');

Beispiel

Schauen wir uns das folgende Beispiel an, das die Verwendung von Observable demonstriert.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Observable Example</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" 
         type = "text/javascript"></script>
   </head>
   
   <body>
      <!-- This is called "view" of HTML markup that defines the appearance of UI -->

      <p>Enter your name: <input data-bind = "value: yourName" /></p>
      <p>Hi <strong data-bind = "text: yourName"></strong> Good Morning!!!</p>

      <script>
         <!-- This is called "viewmodel". This javascript section defines the data and behavior of UI -->

         function AppViewModel() {
            this.yourName = ko.observable("");
         }

         // Activates knockout.js
         ko.applyBindings(new AppViewModel());
      </script>
   </body>
</html>

Die folgende Zeile ist für das Eingabefeld. Wie zu sehen ist, haben wir das Attribut data-bind verwendet, um den Wert yourName an ViewModel zu binden.

<p>Enter your name: <input data-bind = "value: yourName" /> <p>

In der folgenden Zeile wird nur der Wert Ihres Namens gedruckt. Beachten Sie, dass hier der Datenbindungstyp der Text ist, da wir einfach den Wert lesen.

<p>Hi <strong data-bind = "text: yourName"></strong> Good Morning!!!</p>

In der folgenden Zeile behält ko.observable die Variable yourName im Auge, um Änderungen an Daten vorzunehmen. Sobald eine Änderung vorliegt, werden auch die entsprechenden Stellen mit dem geänderten Wert aktualisiert. Wenn Sie den folgenden Code ausführen, wird ein Eingabefeld angezeigt. Wenn Sie dieses Eingabefeld aktualisieren, wird der neue Wert an den Stellen angezeigt oder aktualisiert, an denen er verwendet wird.

this.yourName = ko.observable("");

Ausgabe

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in first_observable_pgm.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Geben Sie den Namen als Scott ein und beachten Sie, dass sich der Name in der Ausgabe widerspiegelt.

Datenänderungen können entweder über die Benutzeroberfläche oder über ViewModel erfolgen. Unabhängig davon, von wo aus die Daten geändert werden, synchronisieren die Benutzeroberfläche und ViewModel die Synchronisierung zwischen ihnen. Dies macht es zu einem Zwei-Wege-Bindungsmechanismus. Wenn Sie im obigen Beispiel Ihren Namen im Eingabefeld ändern, erhält ViewModel einen neuen Wert. Wenn Sie IhreName-Eigenschaft in ViewModel ändern, erhält die Benutzeroberfläche einen neuen Wert.

Observablen lesen und schreiben

In der folgenden Tabelle sind die Lese- und Schreibvorgänge aufgeführt, die für Observables ausgeführt werden können.

Sr.Nr. Lese- / Schreibvorgang & Syntax
1

Read

Um den Wert zu lesen, rufen Sie einfach die Observable-Eigenschaft ohne Parameter wie: AppViewModel.yourName () auf;

2

Write

Um einen Wert in die Observable-Eigenschaft zu schreiben / zu aktualisieren, übergeben Sie einfach den gewünschten Wert in einem Parameter wie: AppViewModel.yourName ('Bob');

3

Write multiple

Mehrere ViewModel-Eigenschaften können mithilfe einer Verkettungssyntax in einer Zeile aktualisiert werden: AppViewModel.yourName ('Bob'). YourAge (45);

Beobachtbare Arrays

Die beobachtbare Deklaration kümmert sich um Datenänderungen eines einzelnen Objekts. ObservableArray arbeitet mit der Sammlung von Objekten. Dies ist eine sehr nützliche Funktion, wenn Sie mit komplexen Anwendungen arbeiten, die mehrere Arten von Werten enthalten und deren Status häufig basierend auf den Benutzeraktionen ändern.

Syntax

this.arrayName = ko.observableArray();    // It's an empty array

Das beobachtbare Array verfolgt nur, welche Objekte darin hinzugefügt oder entfernt werden. Es wird nicht benachrichtigt, ob die Eigenschaften des einzelnen Objekts geändert werden.

Initialisieren Sie es zum ersten Mal

Sie können Ihr Array initialisieren und gleichzeitig als Observable deklarieren, indem Sie die Anfangswerte wie folgt an den Konstruktor übergeben.

this.arrayName = ko.observableArray(['scott','jack']);

Lesen aus dem beobachtbaren Array

Sie können wie folgt auf Observable-Array-Elemente zugreifen.

alert('The second element is ' + arrayName()[1]);

ObservableArray-Funktionen

KnockoutJS verfügt über einen eigenen Satz von Observable-Array-Funktionen. Sie sind bequem, weil -

  • Diese Funktionen funktionieren in allen Browsern.

  • Diese Funktionen übernehmen automatisch die Abhängigkeitsverfolgung.

  • Die Syntax ist einfach zu bedienen. Um beispielsweise ein Element in ein Array einzufügen, müssen Sie nur arrayName.push ('value') anstelle von arrayName (). Push ('value') verwenden.

Im Folgenden finden Sie eine Liste verschiedener Observable Array-Methoden.

Sr.Nr. Methoden & Beschreibung
1 push ('Wert')

Fügt am Ende des Arrays ein neues Element ein.

2 Pop()

Entfernt das letzte Element aus dem Array und gibt es zurück.

3 Verschieben ('Wert')

Fügt am Anfang des Arrays einen neuen Wert ein.

4 Verschiebung()

Entfernt das erste Element aus dem Array und gibt es zurück.

5 umkehren()

Kehrt die Reihenfolge des Arrays um.

6 Sortieren()

Sortiert Array-Elemente in aufsteigender Reihenfolge.

7 Spleiß (Startindex, Endindex)

Akzeptiert zwei Parameter - Startindex und Endindex - entfernt Elemente, die vom Anfangs- bis zum Endindex beginnen, und gibt sie als Array zurück.

8 indexOf ('Wert')

Diese Funktion gibt den Index des ersten Auftretens des angegebenen Parameters zurück.

9 Slice (Startindex, Endindex)

Diese Methode schneidet einen Teil eines Arrays aus. Gibt die Elemente vom Startindex bis zum Endindex zurück.

10 alles entfernen()

Entfernt alle Elemente und gibt sie als Array zurück.

11 entfernen ('Wert')

Entfernt Elemente, die dem Parameter entsprechen, und gibt sie als Array zurück.

12 entfernen (Funktion (Element) {Bedingung})

Entfernt Elemente, die die Bedingung erfüllen, und gibt sie als Array zurück.

13 entfernen ([Wertesatz])

Entfernt Elemente, die mit einem bestimmten Wertesatz übereinstimmen.

14

destroyAll()

Markiert alle Elemente in einem Array mit der Eigenschaft _destroy mit dem Wert true.

15

destroy('value')

Sucht nach einem Element, das dem Parameter entspricht, und markiert es mit einer speziellen Eigenschaft _destroy mit dem Wert true.

16

destroy(function(item) { condition})

Findet alle Elemente, die die Bedingung erfüllen, und markiert sie mit der Eigenschaft _destroy mit dem wahren Wert.

17

destroy([set of values])

Findet die Elemente, die mit einem bestimmten Wertesatz übereinstimmen, und markiert sie als _destroy mit dem wahren Wert.

Note - Destroy- und DestroyAll-Funktionen von ObservableArrays sind hauptsächlich für Entwickler von 'Ruby on Rails' vorgesehen.

Wenn Sie die Methode destroy verwenden, werden die entsprechenden Elemente zu diesem Zeitpunkt nicht wirklich aus dem Array gelöscht, sondern ausgeblendet, indem Sie sie mit der Eigenschaft _destroy mit true value markieren, damit sie nicht von der Benutzeroberfläche gelesen werden können. Elemente, die als _destroy gleich true markiert sind, werden später beim Umgang mit dem JSON-Objektdiagramm gelöscht.

Computed Observable ist eine Funktion, die von einem oder mehreren Observables abhängig ist und automatisch aktualisiert wird, wenn sich die zugrunde liegenden Observables (Abhängigkeiten) ändern.

Berechnete Observablen können verkettet werden.

Syntax

this.varName = ko.computed(function(){
   ...
   ... //  function code
   ...
},this);

Beispiel

Schauen wir uns das folgende Beispiel an, das die Verwendung von Computed Observables demonstriert.

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Computed Observables</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"></script>
   </head>

   <body>
      <p>Enter first number: <input data-bind = "value: a" /></p>
      <p>Enter second number: <input data-bind = "value: b"/></p>
      <p>Average := <span data-bind="text: totalAvg"></span></p>

      <script>
         function MyViewModel() {
            this.a = ko.observable(10);
            this.b = ko.observable(40);

            this.totalAvg = ko.computed(function() {

               if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
                  this.a(Number(this.a()));   //convert string to Number
                  this.b(Number(this.b()));   //convert string to Number
               }

               total = (this.a() + this.b())/2 ;
               return total;
            },this);
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

In den folgenden Zeilen dienen die ersten beiden zum Akzeptieren von Eingabewerten. Die dritte Zeile gibt den Durchschnitt dieser beiden Zahlen aus.

<p>Enter first number: <input data-bind = "value: a" /></p>
<p>Enter second number: <input data-bind = "value: b"/></p>
<p>Average := <span data-bind = "text: totalAvg"></span></p>

Geben Sie in den folgenden Zeilen den Typ der Observablen ein a und bist die Nummer, wenn sie zum ersten Mal in ViewModel initialisiert werden. In KO ist jedoch jede von der Benutzeroberfläche akzeptierte Eingabe standardmäßig im String-Format. Sie müssen also in Number konvertiert werden, um eine arithmetische Operation für sie durchzuführen.

this.totalAvg = ko.computed(function() {
   
   if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
      this.a(Number(this.a()));   //convert string to Number
      this.b(Number(this.b()));   //convert string to Number
   }
   
   total = (this.a() + this.b())/2 ;
   return total;
},this);

In der folgenden Zeile wird der berechnete Durchschnitt in der Benutzeroberfläche angezeigt. Beachten Sie, dass der Datenbindungstyp von totalAvg nur Text ist.

<p>Average := <span data-bind = "text: totalAvg"></span></p>

Ausgabe

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in computed-observable.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Geben Sie 2 beliebige Zahlen in die Textfelder ein und beachten Sie, dass der Durchschnitt berechnet wird.

Verwalten von "Dies"

Beachten Sie, dass im obigen Beispiel der zweite Parameter als bereitgestellt wird thiszur berechneten Funktion. Es ist nicht möglich, auf Observables zu verweisena() und b() ohne Bereitstellung this.

Um dies zu überwinden, self Es wird eine Variable verwendet, die die Referenz von enthält this. Auf diese Weise ist keine Nachverfolgung erforderlichthisim gesamten Code. Stattdessen,self kann verwendet werden.

Der folgende ViewModel-Code wird für das obige Beispiel mit self neu geschrieben.

function MyViewModel(){
   self = this;
   self.a = ko.observable(10);
   self.b = ko.observable(40);

   this.totalAvg = ko.computed(function() {
      
      if(typeof(self.a()) !== "number" || typeof(self.b()) !== "number") {
         self.a(Number(self.a()));   //convert string to Number
         self.b(Number(self.b()));   //convert string to Number
      }
      
      total = (self.a() + self.b())/2 ;
      return total;
   });
}

Reine berechnete Observable

Ein Computed Observable sollte als deklariert werden PureComputed Observable, wenn dieses Observable einfach den Wert berechnet und zurückgibt und die anderen Objekte oder den Status nicht direkt ändert. Pure Computed Observables hilft Knockout dabei, die Neubewertung und die Speichernutzung effizient zu verwalten.

Abonnenten explizit benachrichtigen

Wenn ein Computed Observable einen primitiven Datentypwert (String, Boolean, Null und Number) zurückgibt, werden seine Abonnenten genau dann benachrichtigt, wenn die tatsächliche Wertänderung stattfindet. Wenn ein Observable den gleichen Wert wie der vorherige Wert erhalten hat, werden seine Abonnenten nicht benachrichtigt.

Sie können dafür sorgen, dass Computed Observables die Beobachter immer explizit benachrichtigen, obwohl der neue Wert mit dem alten Wert identisch ist, indem Sie das verwenden notify Syntax wie folgt.

myViewModel.property = ko.pureComputed(function() {
   return ...;    // code logic goes here
}).extend({ notify: 'always' });

Einschränken von Änderungsbenachrichtigungen

Zu viele teure Updates können zu Leistungsproblemen führen. Sie können die Anzahl der Benachrichtigungen, die von Observable empfangen werden sollen, mithilfe von begrenzenrateLimit Attribut wie folgt.

// make sure there are updates no more than once per 100-millisecond period
myViewModel.property.extend({ rateLimit: 100 });

Herausfinden, ob eine Eigenschaft berechnet werden kann

In bestimmten Situationen kann es erforderlich sein, herauszufinden, ob eine Eigenschaft eine berechnete beobachtbare Größe ist. Die folgenden Funktionen können verwendet werden, um die Arten von Observablen zu identifizieren.

Sr.Nr. Funktion
1

ko.isComputed

Kehrt zurück true wenn die Eigenschaft Computed Observable ist.

2

ko.isObservable

Kehrt zurück true Wenn die Eigenschaft Observable, Observable Array oder Computed Observable ist.

3

ko.isWritableObservable

Kehrt zurück truewenn Observable, Observable Array oder Writable Computed Observable. (Dies wird auch als ko.isWriteableObservable bezeichnet.)

Beschreibbare berechnete Observablen

Das berechnete Observable wird von einem oder mehreren anderen Observables abgeleitet und ist daher schreibgeschützt. Es ist jedoch möglich, dass Computed Observable beschreibbar gemacht werden kann. Dazu müssen Sie eine Rückruffunktion bereitstellen, die mit geschriebenen Werten arbeitet.

Diese beschreibbaren berechneten Observablen funktionieren genau wie normale Observablen. Darüber hinaus muss eine benutzerdefinierte Logik erstellt werden, um Lese- und Schreibaktionen zu stören.

Mit der folgenden Verkettungssyntax können Sie vielen Observables- oder Computed Observable-Eigenschaften Werte zuweisen.

myViewModel.fullName('Tom Smith').age(45)

Beispiel

Das folgende Beispiel zeigt die Verwendung von Writable Computable Observable.

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Writable Computed Observable</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
   </head>

   <body>
      <p>Enter your birth Date: <input type = "date" data-bind = "value: rawDate" ></p>
      <p><span data-bind = "text: yourAge"></span></p>

      <script>
         function MyViewModel() {
            this.yourAge = ko.observable();
            today = new Date();
            rawDate = ko.observable();

            this.rawDate = ko.pureComputed ({

               read: function() {
                  return this.yourAge;
               },

               write: function(value) {
                  var b = Date.parse(value);    // convert birth date into milliseconds
                  var t = Date.parse(today);    // convert todays date into milliseconds
                  diff = t - b;                 // take difference
                  var y = Math.floor(diff/31449600000);     // difference is converted
                                                            // into years. 31449600000
                                                            //milliseconds form a year.

                  var m = Math.floor((diff % 31449600000)/604800000/4.3);  // calculating
                                                                           // months.
                                                                           // 604800000
                                                                           // milliseconds
                                                                           // form a week.

                  this.yourAge("You are " + y + " year(s) " + m +" months old.");
               },
               owner: this
            });
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

Im obigen Code rawDate ist eine pureComputed-Eigenschaft, die von der Benutzeroberfläche akzeptiert wird. yourAge Observable wird abgeleitet von rawDate.

Daten in JavaScript werden in Millisekunden bearbeitet. Daher werden beide Daten (heutiges Datum und Geburtsdatum) in Millisekunden umgerechnet, und dann wird die Differenz zwischen ihnen in Jahren und Monaten zurückgerechnet.

Ausgabe

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in writable_computed_observable.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Geben Sie ein beliebiges Geburtsdatum ein und beachten Sie, dass das Alter berechnet wird.

Die deklarative Bindung in KnockoutJS bietet eine leistungsstarke Möglichkeit, Daten mit der Benutzeroberfläche zu verbinden.

Es ist wichtig, die Beziehung zwischen Bindungen und Observablen zu verstehen. Technisch sind diese beiden unterschiedlich. Sie können ein normales JavaScript-Objekt verwenden, da ViewModel und KnockoutJS die View-Bindung korrekt verarbeiten können.

Ohne Observable wird die Eigenschaft von der Benutzeroberfläche nur zum ersten Mal verarbeitet. In diesem Fall kann es nicht automatisch basierend auf der zugrunde liegenden Datenaktualisierung aktualisiert werden. Um dies zu erreichen, müssen Bindungen auf beobachtbare Eigenschaften bezogen werden.

Bindungssyntax

Die Bindung besteht aus 2 Elementen, die Bindung name und value. Das Folgende ist ein einfaches Beispiel -

Today is : <span data-bind = "text: whatDay"></span>

Hier ist Text der Bindungsname und whatDay der Bindungswert. Sie können mehrere Bindungen durch Komma trennen, wie in der folgenden Syntax gezeigt.

Your name: <input data-bind = "value: yourName, valueUpdate: 'afterkeydown'" />

Hier wird der Wert nach jedem Tastendruck aktualisiert.

Bindungswerte

Der Bindungswert kann a sein single value, literal, ein variable oder kann ein sein JavaScriptAusdruck. Wenn sich die Bindung auf einen ungültigen Ausdruck oder eine ungültige Referenz bezieht, erzeugt KO einen Fehler und beendet die Verarbeitung der Bindung.

Es folgen einige Beispiele für Bindungen.

<!-- simple text binding -->
<p>Enter employee name: <input   -bind = 'value: empName' /></p>

<!-- click binding, call a specific function -->
<button data-bind="click: sortEmpArray">Sort Array</button>

<!-- options binding -->
<select multiple = "true" size = "8" data-bind = "options: empArray , 
   selectedOptions: chosenItem"> </select>

Beachten Sie die folgenden Punkte -

  • Leerzeichen machen keinen Unterschied.

  • Ab KO 3.0 können Sie den Bindungswert überspringen, wodurch die Bindung einen undefinierten Wert erhält.

Bindungskontext

Die Daten, die in aktuellen Bindungen verwendet werden, können von einem Objekt referenziert werden. Dieses Objekt wird aufgerufenbinding context.

Die Kontexthierarchie wird von KnockoutJS automatisch erstellt und verwaltet. In der folgenden Tabelle sind die verschiedenen Arten von Bindungskontexten aufgeführt, die von KO bereitgestellt werden.

Sr.Nr. Bindungskontexttypen & Beschreibung
1

$root

Dies bezieht sich immer auf ViewModel der obersten Ebene. Auf diese Weise können Sie auf Methoden der obersten Ebene zugreifen, um ViewModel zu bearbeiten. Dies ist normalerweise das Objekt, das an ko.applyBindings übergeben wird.

2

$data

Diese Eigenschaft ist sehr ähnlich thisSchlüsselwort im Javascript-Objekt. Die Eigenschaft $ data in einem verbindlichen Kontext bezieht sich auf das ViewModel-Objekt für den aktuellen Kontext.

3

$index

Diese Eigenschaft enthält den Index eines aktuellen Elements eines Arrays in einer foreach-Schleife. Der Wert von $ index ändert sich automatisch, wenn das zugrunde liegende Observable-Array aktualisiert wird. Offensichtlich ist dieser Kontext nur für verfügbarforeach Bindungen.

4

$parent

Diese Eigenschaft bezieht sich auf das übergeordnete ViewModel-Objekt. Dies ist nützlich, wenn Sie innerhalb einer verschachtelten Schleife auf äußere ViewModel-Eigenschaften zugreifen möchten.

5

$parentContext

Das Kontextobjekt, das auf der übergeordneten Ebene gebunden ist, wird aufgerufen $parentContext. Das ist anders als$parent. $ parent bezieht sich auf Daten. Während $ parentContext auf den Bindungskontext verweist. Beispielsweise müssen Sie möglicherweise aus einem inneren Kontext auf den Index des äußeren foreach-Elements zugreifen.

6

$rawdata

Dieser Kontext enthält in der aktuellen Situation den unformatierten ViewModel-Wert. Das ähnelt$data but the difference is, if ViewModel is wrapped in Observable, then $Daten werden einfach entpackt. ViewModel und $ rawdata werden zu tatsächlichen beobachtbaren Daten.

7

$component

Dieser Kontext wird verwendet, um auf ViewModel dieser Komponente zu verweisen, wenn Sie sich in einer bestimmten Komponente befinden. Beispielsweise möchten Sie möglicherweise über ViewModel auf eine Eigenschaft zugreifen, anstatt auf aktuelle Daten im Vorlagenabschnitt der Komponente.

8

$componentTemplateNodes

Dies stellt ein Array von DOM-Knoten dar, die an diese bestimmte Komponente übergeben werden, wenn Sie sich in einer bestimmten Komponentenvorlage befinden.

Die folgenden Begriffe sind ebenfalls verbindlich verfügbar, jedoch nicht verbindlich.

  • $context - Dies ist nichts anderes als ein vorhandenes verbindliches Kontextobjekt.

  • $element - Dieses Objekt bezieht sich auf ein Element in DOM in der aktuellen Bindung.

Arbeiten mit Text und Darstellungen

Im Folgenden finden Sie eine Liste der von KO bereitgestellten Bindungstypen für den Umgang mit Text und visuellen Darstellungen.

Sr.Nr. Bindungsart & Verwendung
1 sichtbar:

Anzeigen oder Ausblenden von HTML-DOM-Elementen in Abhängigkeit von bestimmten Bedingungen.

2 Text:

So legen Sie den Inhalt eines HTML-DOM-Elements fest

3 html:

So legen Sie den HTML-Markup-Inhalt eines DOM-Elements fest

4 CSS:

So wenden Sie CSS-Klassen auf ein Element an

5 Stil:

Definieren des Inline-Stilattributs eines Elements.

6 attr:

Dynamisches Hinzufügen von Attributen zu einem Element.

Arbeiten mit Kontrollflussbindungen

Im Folgenden finden Sie eine Liste der von KO bereitgestellten Kontrollflussbindungstypen.

Sr.Nr. Bindungsart & Verwendung
1 foreach:

In dieser Bindung wird jedes Array-Element im HTML-Markup in einer Schleife referenziert.

2 if:

Wenn die Bedingung erfüllt ist, wird das angegebene HTML-Markup verarbeitet. Andernfalls wird es aus DOM entfernt.

3 ifnot:

Negation von If. Wenn die Bedingung erfüllt ist, wird das angegebene HTML-Markup verarbeitet. Andernfalls wird es aus DOM entfernt.

4 mit:

Diese Bindung wird verwendet, um die untergeordneten Elemente eines Objekts im Kontext des angegebenen Objekts zu binden.

5 Komponente: ODER Komponente:

Diese Bindung wird verwendet, um eine Komponente in DOM-Elemente einzufügen und die Parameter optional zu übergeben.

Arbeiten mit Formularfeldbindungen

Im Folgenden finden Sie eine Liste der von KO bereitgestellten Formularfelder-Bindungstypen.

Sr.Nr. Bindungsart & Verwendung
1 Klicken Sie auf:

Diese Bindung wird verwendet, um eine JavaScript-Funktion aufzurufen, die einem DOM-Element basierend auf einem Klick zugeordnet ist.

2 Ereignis:

Diese Bindung wird verwendet, um die angegebenen DOM-Ereignisse abzuhören und zugehörige Handlerfunktionen basierend darauf aufzurufen.

3 Senden:

Diese Bindung wird verwendet, um eine JavaScript-Funktion aufzurufen, wenn das zugehörige DOM-Element gesendet wird.

4 enable:

Diese Bindung wird verwendet, um bestimmte DOM-Elemente basierend auf einer bestimmten Bedingung zu aktivieren.

5 deaktivieren:

Diese Bindung deaktiviert das zugehörige DOM-Element, wenn der Parameter true ergibt.

6 Wert:

Diese Bindung wird verwendet, um den Wert des jeweiligen DOM-Elements mit der ViewModel-Eigenschaft zu verknüpfen.

7 textInput:

Diese Bindung wird verwendet, um eine bidirektionale Bindung zwischen Textfeld oder Textbereich und ViewModel-Eigenschaft zu erstellen.

8 hasFocus:

Diese Bindung wird verwendet, um den Fokus eines HTML-DOM-Elements manuell über eine ViewModel-Eigenschaft festzulegen.

9 aktiviert:

Diese Bindung wird verwendet, um eine Verknüpfung zwischen einem überprüfbaren Formularelement und der ViewModel-Eigenschaft herzustellen.

10 Optionen:

Diese Bindung wird verwendet, um die Optionen für ein ausgewähltes Element zu definieren.

11 selectedOptions:

Diese Bindung wird verwendet, um mit Elementen zu arbeiten, die derzeit im Steuerelement für die Auswahl mehrerer Listen ausgewählt sind.

12 uniqueName:

Diese Bindung wird verwendet, um einen eindeutigen Namen für ein DOM-Element zu generieren.

KnockoutJs verfolgt automatisch die Abhängigkeiten, wenn die Werte aktualisiert werden. Es hat ein einzelnes Objekt namensdependency tracker (ko.dependencyDetection), das als Zwischenprodukt zwischen den beiden Parteien zum Abonnieren der Abhängigkeiten fungiert.

Es folgt der Algorithmus zur Abhängigkeitsverfolgung.

Step 1 - Immer wenn Sie ein berechnetes Observable deklarieren, ruft KO sofort seine Evaluatorfunktion auf, um seinen Anfangswert zu erhalten.

Step 2- Das Abonnement wird für alle vom Evaluator gelesenen Beobachtungen eingerichtet. In einer Anwendung werden die alten Abonnements, die nicht mehr verwendet werden, entsorgt.

Step 3 - KO benachrichtigt schließlich das aktualisierte berechnete Observable.

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJS How Dependency Tracking Works</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div>
         <form data-bind = "submit: addFruits">
            <b>Add Fruits:</b>
            <input data-bind = 'value: fruitToAdd, valueUpdate: "afterkeydown"'/>
            <button type = "submit" data-bind = "enable: fruitToAdd().length > 0">Add</button>
            <p><b>Your fruits list:</b></p>
            <select multiple = "multiple" width = "50" data-bind = "options: fruits"> </select>
         </form>
      </div>
      
      <script>
         var Addfruit = function(fruits) {
            this.fruits = ko.observableArray(fruits);
            this.fruitToAdd = ko.observable("");
            
            this.addFruits = function() {
               
               if (this.fruitToAdd() != "") {
                  this.fruits.push(this.fruitToAdd());   // Adds a fruit
                  this.fruitToAdd("");                   // Clears the text box
               }
                
            }.bind(this);                                // "this" is the view model
         };

         ko.applyBindings(new Addfruit(["Apple", "Orange", "Banana"]));
      </script>
      
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in dependency_tracking.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Geben Sie einen beliebigen Fruchtnamen ein und klicken Sie auf die Schaltfläche Hinzufügen.

Abhängigkeiten mit Peek steuern

Auf das Computed Observable kann zugegriffen werden, ohne eine Abhängigkeit zu erstellen, indem Sie das verwenden peekFunktion. Es steuert das Observable durch Aktualisieren der berechneten Eigenschaft.

Example

<!DOCTYPE html>
<html>
   <head>
      <title>KnockoutJs Controlling Dependencies Using Peek</title>
      <!-- CDN's-->
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <div class = "logblock">
         <h3>Computed Log</h3>
         <pre class = "log" data-bind = "html: computedLog"></pre>
      </div>

      <script>
         function AppData() {
            this.firstName = ko.observable('John');
            this.lastName = ko.observable('Burns');
            this.computedLog = ko.observable('Log: ');
            
            this.fullName = ko.computed(function () {
               var value = this.firstName() + " " + this.lastName();
               this.computedLog(this.computedLog.peek() + value + '; <br/>');
               return value;
            }, this);

            this.step = ko.observable(0);
            this.next = function () {
               this.step(this.step() === 2 ? 0 : this.step()+1);
            };
         };
         
         ko.applyBindings(new AppData());
      </script>
      
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in dependency_tracking_peek.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

Beobachtungen

Ignorieren von Abhängigkeiten innerhalb einer berechneten Abhängigkeit

Das ko.ignoreDependenciesMit dieser Funktion können Sie die Abhängigkeiten ignorieren, die Sie in den berechneten Abhängigkeiten nicht verfolgen möchten. Es folgt die Syntax.

ko.ignoreDependencies( callback, callbackTarget, callbackArgs );

Warum kreisförmige Abhängigkeiten nicht sinnvoll sind

Wenn KO eine berechnete beobachtbare Größe auswertet, wird eine Auswertung der abhängigen berechneten beobachtbaren Größe nicht neu gestartet. Daher ist es nicht sinnvoll, Zyklen in Ihre Abhängigkeitsketten aufzunehmen.

Templateist eine Reihe von DOM-Elementen, die wiederholt verwendet werden können. Templating erleichtert das Erstellen komplexer Anwendungen, da die Duplizierung von DOM-Elementen minimiert wird.

Es gibt zwei Möglichkeiten, Vorlagen zu erstellen.

  • Native templating- Diese Methode unterstützt die Kontrollflussbindungen wie foreach, with und if. Diese Bindungen erfassen das im Element vorhandene HTML-Markup und verwenden es als Vorlage für zufällige Elemente. Für diese Vorlage ist keine externe Bibliothek erforderlich.

  • String-based templating- KO stellt eine Verbindung zur Engine eines Drittanbieters her, um ViewModel-Werte zu übergeben, und fügt das resultierende Markup in das Dokument ein. Zum Beispiel JQuery.tmpl und Underscore Engine.

Syntax

template: <parameter-value>

<script type = "text/html" id = "template-name">
   ...
   ...   // DOM elemets to be processed
   ...
</script>

Beachten Sie, dass type wird bereitgestellt als text/html Im Skriptblock, um KO darüber zu informieren, handelt es sich nicht um einen ausführbaren Block, sondern nur um einen Vorlagenblock, der gerendert werden muss.

Parameters

Die Kombination der folgenden Eigenschaften kann als Parameterwert an die Vorlage gesendet werden.

  • name - Dies ist der Name der Vorlage.

  • nodes- Dies stellt ein Array von DOM-Knoten dar, die als Vorlage verwendet werden sollen. Dieser Parameter wird ignoriert, wenn der Parameter name übergeben wird.

  • data - Dies sind nur Daten, die über die Vorlage angezeigt werden sollen.

  • if - Die Vorlage wird zugestellt, wenn die angegebene Bedingung einen wahren oder wahren Wert ergibt.

  • foreach - Vorlage im foreach-Format bereitstellen.

  • as - Dies dient nur zum Erstellen eines Alias ​​in foreach-Elementen.

  • afterAdd, afterRender, beforeRemove - Dies sind alles aufrufbare Funktionen, die abhängig von der ausgeführten Operation ausgeführt werden sollen.

Beobachtungen

Rendern einer benannten Vorlage

Vorlagen werden implizit durch HTML-Markup in DOM definiert, wenn sie mit Kontrollflussbindungen verwendet werden. Wenn Sie möchten, können Sie Vorlagen jedoch in ein separates Element zerlegen und dann nach Namen referenzieren.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Named Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', data: friend1 }"></div>
      <div data-bind = "template: { name: 'friend-template', data: friend2 }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friend1 = { 
               name: 'Smith', 
               contactNumber: 4556750345, 
               email: '[email protected]' 
            };
            
            this.friend2 = { 
               name: 'Jack', 
               contactNumber: 6789358001, 
               email: '[email protected]' 
            };
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in template-named.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Hier wird die Friend-Vorlage 2 Mal verwendet.

Verwenden von "foreach" in der Vorlage

Das Folgende ist ein Beispiel für die Verwendung foreach Parameter zusammen mit dem Vorlagennamen.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - foreach used with Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { name: 'friend-template', foreach: friends }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = [
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
               { name: 'Lisa', contactNumber: 4567893131, email: '[email protected]' }
            ]
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in template-foreach.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Hier wird jede Kontrolle bei der Vorlagenbindung verwendet.

Erstellen eines Alias ​​Verwenden als Schlüsselwort für jedes Element

Im Folgenden wird beschrieben, wie ein Alias ​​für ein foreach-Element erstellt werden kann:

<div data-bind = "template: { 
   name: 'friend-template', 
   foreach: friends, 
   as: 'frnz' 
}"></div>

Durch Erstellen eines Alias ​​wird es einfach, aus foreach-Schleifen heraus auf übergeordnete Objekte zu verweisen. Diese Funktion ist nützlich, wenn der Code komplex und auf mehreren Ebenen verschachtelt ist.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - using alias in Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <ul data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends, 
         as: 'frnz' 
      }"></ul>

      <script type = "text/html" id = "friend-template">
         <li>
            <h3 data-bind = "text: name"></h3>
            <span>Contact Numbers</span>
            <ul data-bind = "template: { 
               name : 'contacts-template', 
               foreach:contactNumber, 
               as: 'cont'
            } "></ul>
            <p>Email-id: <span data-bind = "text: email"></span></p>
         </li>
      </script>

      <script type = "text/html" id = "contacts-template">
         <li>
            <p><span data-bind = "text: cont"></span></p>
         </li>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            this.friends = ko.observableArray ( [
               { 
                  name: 'Smith', 
                  contactNumber: [ 4556750345, 4356787934 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Jack', 
                  contactNumber: [ 6789358001, 3456895445 ], 
                  email: '[email protected]' 
               },
               
               { 
                  name: 'Lisa', 
                  contactNumber: [ 4567893131, 9876456783, 1349873445 ],  
                  email: '[email protected]' 
               }
            ]);
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in template-as-alias.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Alias ​​wird anstelle des vollständigen Namens der Arrays verwendet.

Verwenden von afterAdd, beforeRemove und afterRender

Es gibt Situationen, in denen zusätzliche benutzerdefinierte Logik für von der Vorlage erstellte DOM-Elemente ausgeführt werden muss. In diesem Fall können folgende Rückrufe verwendet werden. Bedenken Sie, dass Sie dann jedes Element verwenden -

afterAdd - Diese Funktion wird aufgerufen, wenn dem in foreach genannten Array ein neues Element hinzugefügt wird.

beforeRemove - Diese Funktion wird unmittelbar vor dem Entfernen des Elements aus einem in foreach genannten Array aufgerufen.

afterRender - Die hier erwähnte Funktion wird jedes Mal aufgerufen, wenn foreach gerendert und neue Einträge zum Array hinzugefügt werden.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Use of afterRender Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
      <script src = "https://code.jquery.com/jquery-2.1.3.min.js"
         type = "text/javascript"></script>
   </head>

   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: 'friend-template', 
         foreach: friends , 
         afterRender: afterProcess
      }"></div>

      <script type = "text/html" id = "friend-template">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
         <p>Email-id: <span data-bind = "text: email"></span></p>
         <button data-bind = "click: $root.removeContact">remove </button>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
            self = this;
            this.friends = ko.observableArray ([
               { name: 'Smith', contactNumber: 4556750345, email: '[email protected]' },
               { name: 'Jack', contactNumber: 6789358001, email: '[email protected]' },
            ])

            this.afterProcess = function(elements, data){
               $(elements).css({color: 'magenta' });
            }

            self.removeContact = function() {
               self.friends.remove(this);
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in template-afterrender.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Hier wird die afterProcess-Funktion jedes Mal ausgeführt, wenn foreach gerendert wird.

Vorlage dynamisch auswählen

Wenn mehrere Vorlagen verfügbar sind, kann eine dynamisch ausgewählt werden, indem der Name als festgelegt wird observableParameter. Daher wird der Vorlagenwert neu ausgewertet, wenn sich der Namensparameter ändert, und die Daten werden wiederum neu gerendert.

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Templating - Dynamic Template</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <h2>Friends List</h2>
      Here are the Friends from your contact page:
      <div data-bind = "template: { 
         name: whichTemplate, 
         foreach: friends 
      }"></div>

      <script type = "text/html" id = "only-phon">
         <h3 data-bind = "text: name"></h3>
         <p>Contact Number: <span data-bind = "text: contactNumber"></span></p>
      </script>

      <script type = "text/html" id = "only-email">
         <h3 data-bind = "text: name"></h3>
         <p>Email-id: <span data-bind = "text: email"></span></p>
      </script>

      <script type = "text/javascript">
         function MyViewModel() {
   
            this.friends = ko.observableArray ([
               {
                  name: 'Smith', 
                  contactNumber: 4556750345, 
                  email: '[email protected]', 
                  active: ko.observable(true)
               },
               
               {
                  name: 'Jack', 
                  contactNumber: 6789358001, 
                  email: '[email protected]', 
                  active: ko.observable(false)
               },
            ]);

            this.whichTemplate = function(friends) {
               return friends.active() ? "only-phon" : "only-email";
            }
         }

         var vm = new MyViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in template-dynamic.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

  • Die zu verwendende Vorlage wird abhängig vom aktiven Flag-Wert festgelegt.

Verwenden externer String-basierter Engines

Das native Templating funktioniert auch mit verschachtelten Codeblöcken perfekt mit verschiedenen Kontrollflusselementen. KO bietet auch eine Möglichkeit zur Integration in externe Vorlagenbibliotheken wie Underscore Templating Engine oder JQuery.tmpl.

Wie auf der offiziellen Website erwähnt, befindet sich JQuery.tmpl seit Dezember 2011 nicht mehr in der aktiven Entwicklung. Daher wird das native Templating von KO nur anstelle von JQuery.tmpl oder einer anderen stringbasierten Template-Engine empfohlen.

Weitere Informationen hierzu finden Sie auf der offiziellen Website .

Komponenten sind eine großartige Möglichkeit, den UI-Code zu organisieren, um eine große Anwendung zu strukturieren und die Wiederverwendbarkeit von Code zu fördern.

Es wird von einer anderen Komponente geerbt oder verschachtelt. Zum Laden und Konfigurieren werden eigene Konventionen oder Logik definiert.

Es ist zur Wiederverwendung in der gesamten Anwendung oder im Projekt verpackt. Repräsentiert die vollständigen Abschnitte der Anwendung oder kleine Steuerelemente / Widgets. Es kann bei Bedarf geladen oder vorgeladen werden.

Komponentenregistrierung

Komponenten können sich mit dem registrieren ko.components.register()API. Es hilft, die Komponenten in KO zu laden und darzustellen. Der Komponentenname mit Konfiguration wird für die Registrierung erwartet. Die Konfiguration gibt an, wie das viewModel und die Vorlage ermittelt werden.

Syntax

Komponenten können wie folgt registriert werden:

ko.components.register('component-name', {
   viewModel: {...},    //function code
   template: {....)	//function code
});
  • Das component-name kann eine beliebige nicht leere Zeichenfolge sein.

  • viewModel ist optional und kann jedes der in den nächsten Abschnitten aufgeführten viewModel-Formate annehmen.

  • template ist erforderlich und kann jedes der in den nächsten Abschnitten aufgeführten Vorlagenformate annehmen.

Angeben eines ViewModel

In der folgenden Tabelle sind die viewModel-Formate aufgeführt, mit denen die Komponenten registriert werden können.

Sr.Nr. viewModel Forms & Description
1

constructor function

Es wird für jede Komponente ein separates viewModel-Objekt erstellt. Das Objekt oder die Funktion wird zum Binden in der Komponentenansicht verwendet.

function SomeComponentViewModel(params) {
   this.someProperty = params.something;
}
ko.components.register('component name', {
   viewModel: SomeComponentViewModel,
   template: ...
});
2

shared object instance

Die viewModel-Objektinstanz wird gemeinsam genutzt. Die Instanzeigenschaft wird übergeben, um das Objekt direkt zu verwenden.

var sharedViewModelInstance = { ... };

ko.components.register('component name', {
   viewModel: { instance: sharedViewModelInstance },
   template: ...
});
3

createViewModel

Es ruft eine Funktion auf, die als Factory fungiert und als Ansichtsmodell verwendet werden kann, das ein Objekt zurückgeben kann.

ko.components.register('component name', {  
   viewModel: {  
      createViewModel: function (params, componentInfo) {  
         ...       //function code  
         ...
      }  
   },  
   template: ....  
});
4

AMD module

Es ist ein Modulformat zum Definieren von Modulen, bei denen sowohl Modul als auch Abhängigkeiten asynchron geladen werden.

ko.components.register('component name', {
   viewModel: { require: 'some/module/name' },
   template: ...
});

define(['knockout'], function(ko) {
   function MyViewModel() {
      // ...
   }

   return MyViewModel;
});

Vorlage angeben

In der folgenden Tabelle sind die Vorlagenformate aufgeführt, mit denen die Komponenten registriert werden können.

Sr.Nr. Vorlagenformulare
1

element ID

ko.components.register('component name', {
   template: { element: 'component-template' },
   viewModel: ...
});
2

element instance

var elemInstance = document.getElementById('component-template');

ko.components.register('component name', {
   template: { element: elemInstance },
   viewModel: ...
});
3

string of markup

ko.components.register('component name', {
   template: '<input data-bind = "value: yourName" />\
      <button data-bind = "click: addEmp">Add Emp </button>',
   viewModel: ...
});
4

DOM nodes

var emp = [
   document.getElementById('node 1'),
   document.getElementById('node 2'),
];

ko.components.register('component name', {
   template: emp,
   viewModel: ...
});
5

document fragement

ko.components.register('component name', {
   template: someDocumentFragmentInstance,
   viewModel: ...
});
6

AMD module

ko.components.register('component name', {
   template: { require: 'some/template' },
   viewModel: ...
});

Komponenten, die als einzelnes AMD-Modul registriert sind

Das AMD-Modul kann eine Komponente selbst registrieren, ohne das viewModel / Template-Paar zu verwenden.

ko.components.register('component name',{ require: 'some/module'});

Komponentenbindung

Es gibt zwei Möglichkeiten der Komponentenbindung.

  • Full syntax- Der Parameter und das Objekt werden an die Komponente übergeben. Es kann mit den folgenden Eigenschaften übergeben werden.

    • name - Es fügt den Komponentennamen hinzu.

    • params - Es können mehrere Parameter im Objekt an der Komponente übergeben werden.

<div data-bind='component: {
   name: "tutorials point",
   params: { mode: "detailed-list", items: productsList }
}'>
</div>
  • Shorthand syntax - Es übergibt die Zeichenfolge als Komponentennamen und enthält keine Parameter.

<div data-bind = 'component: "component name"'></div>
  • Template-only components - Komponenten können nur Vorlagen definieren, ohne das viewModel anzugeben.

ko.components.register('component name', {
   template:'<input data-bind = "value: someName" />,
});
  • Using Component without a container element- Komponenten können ohne zusätzliches Containerelement verwendet werden. Dies kann mit erfolgencontainerless flow Steuerung, die dem Kommentar-Tag ähnlich ist.

<!--ko.component: ""-->
<!--/ko-->

Benutzerdefiniertes Element

Benutzerdefiniertes Element ist eine Möglichkeit zum Rendern einer Komponente. Hier können Sie direkt einen selbstbeschreibenden Markup-Elementnamen schreiben, anstatt einen Platzhalter zu definieren, durch den die Komponenten gebunden werden.

<products-list params = "name: userName, type: userType"></products-list>

Parameter übergeben

paramsDas Attribut wird verwendet, um den Parameter an die Komponente viewModel zu übergeben. Es ähnelt dem Datenbindungsattribut. Der Inhalt des params-Attributs wird wie ein JavaScript-Objektliteral interpretiert (genau wie ein Datenbindungsattribut), sodass Sie beliebige Werte eines beliebigen Typs übergeben können. Es kann den Parameter auf folgende Weise übergeben:

  • Communication between parent and child components- Die Komponente wird nicht von selbst instanziiert, sodass die Eigenschaften des Ansichtsmodells von außerhalb der Komponente referenziert werden und somit vom Ansichtsmodell der untergeordneten Komponente empfangen werden. Zum Beispiel können Sie in der folgenden Syntax sehen, dassModelValue ist das übergeordnete Ansichtsmodell, das vom untergeordneten viewModel-Konstruktor empfangen wird ModelProperty.

  • Passing observable expressions - Der Parameter params enthält drei Werte.

    • simpleExpression- Es ist ein numerischer Wert. Es handelt sich nicht um Observable.

    • simpleObservable- Es ist eine Instanz, die im übergeordneten viewModel definiert ist. Das übergeordnete viewModel erhält automatisch die Änderungen an Observable, die vom untergeordneten viewModel vorgenommen wurden.

    • observableExpression- Ausdruck liest das Beobachtbare, wenn der Ausdruck selbst ausgewertet wird. Wenn sich der beobachtbare Wert ändert, kann sich auch das Ergebnis des Ausdrucks im Laufe der Zeit ändern.

Wir können die Parameter wie folgt übergeben:

<some-component
   params = 'simpleExpression: 1 + 1,
      simpleObservable: myObservable,
      observableExpression: myObservable() + 1'>
</some-component>

Wir können die Parameter in viewModel wie folgt übergeben:

<some-component
   params = 'objectValue:{a: 3, b: 2},
      dateValue: new date(),
      stringValue: "Hi",
      numericValue:123,
      boolValue: true/false,
      ModelProperty: ModelValue'>
</some-component>

Markup an Komponenten übergeben

Das empfangene Markup wird zum Erstellen einer Komponente verwendet und als Teil der Ausgabe ausgewählt. Folgende Knoten werden als Teil der Ausgabe in der Komponentenvorlage übergeben.

template: { nodes: $componentTemplateNodes }

Steuern von benutzerdefinierten Element-Tag-Namen

Die Namen, die Sie in den Komponenten mit registrieren ko.components.registerDer gleiche Name entspricht den Namen der benutzerdefinierten Element-Tags. Wir können die Namen der benutzerdefinierten Element-Tags ändern, indem wir sie überschreiben, um sie zu steuerngetComponentNameForNode.

ko.components.getComponentNameForNode = function(node) {
   ...
   ...   //function code
   ...
}

Registrieren von benutzerdefinierten Elementen

Die benutzerdefinierten Elemente können sofort verfügbar gemacht werden, wenn der Standard-Komponentenlader verwendet wird und daher die Komponente mit registriert wird ko.components.register. Wenn wir das nicht benutzenko.components.registerWenn Sie den benutzerdefinierten Komponentenlader implementieren, kann das benutzerdefinierte Element verwendet werden, indem ein beliebiger Elementname Ihrer Wahl definiert wird. Bei der Verwendung muss keine Konfiguration angegeben werdenko.components.register da der benutzerdefinierte Komponentenlader ihn nicht mehr verwendet.

ko.components.register('custom-element', { ......... });

Example

<!DOCTYPE html>
   <head>
      <title>KnockoutJS Components</title>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      <script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
   </head>
   
   <body>
      <!--params attribute is used to pass the parameter to component viewModel.-->
      <click params = "a: a, b: b"></click>

      <!--template is used for a component by specifying its ID -->
      <template id = "click-l">
         <div data-bind = "text: a"></div>

         <!--Use data-bind attribute to bind click:function() to ViewModel. -->
         <button data-bind = "click:function(){callback(1)}">Increase</button>
         <button data-bind = "click:function(){callback(-1)}">Decrease</button>
      </template>

      <script>
         //Here components are registered
         ko.components.register('click', {
            
            viewModel: function(params) {
               self = this;
               this.a = params.a;
               this.b = params.b;

               this.callback = function(num) {
                  self.b(parseInt(num));
                  self.a( self.a() + parseInt(num) );
               };
            },
            template: { element: 'click-l' }
         });

         //keeps an eye on variable for any modification in data
         function viewModel() {
            this.a = ko.observable(2);
            this.b = ko.observable(0);
         }

         ko.applyBindings(new viewModel() );
      </script>
      
   </body>
</html>

Output

Führen Sie die folgenden Schritte aus, um zu sehen, wie der obige Code funktioniert:

  • Speichern Sie den obigen Code in component_register.htm Datei.

  • Öffnen Sie diese HTML-Datei in einem Browser.

Komponentenlader

Komponentenlader werden verwendet, um das Template / ViewModel-Paar für den angegebenen Komponentennamen asynchron zu übergeben.

Der Standard-Komponentenlader

Der Standard-Komponentenlader hängt von der explizit registrierten Konfiguration ab. Jede Komponente wird vor Verwendung der Komponente registriert.

ko.components.defaultLoader

Funktionen des Component Loader-Dienstprogramms

Der Standard-Komponentenlader kann mit den folgenden Funktionen lesen und schreiben.

Sr.Nr. Dienstprogrammfunktionen & Beschreibung
1

ko.components.register(name, configuration)

Komponente ist registriert.

2

ko.components.isRegistered(name)

Wenn der jeweilige Komponentenname bereits registriert ist, wird er als true oder false zurückgegeben.

3

ko.components.unregister(name)

Der Komponentenname wird aus der Registrierung entfernt.

4

ko.components.get(name, callback)

Diese Funktion geht nacheinander an jeden registrierten Loader, um herauszufinden, wer als erstes die viewModel / Template-Definition für den Komponentennamen übergeben hat. Anschließend wird durch Aufrufen die viewModel / template-Deklaration zurückgegebencallback. Wenn der registrierte Loader nichts über die Komponente finden konnte, wird er aufgerufencallback(null).

5

ko.components.clearCachedDefinition(name)

Diese Funktion kann aufgerufen werden, wenn der angegebene Komponenten-Cache-Eintrag gelöscht werden soll. Wenn die Komponente das nächste Mal benötigt wird, werden erneut die Lader konsultiert.

Implementieren eines benutzerdefinierten Komponentenladers

Der benutzerdefinierte Komponentenlader kann auf folgende Arten implementiert werden:

  • getConfig(name, callback)- Abhängig von den Namen können wir Konfigurationen programmgesteuert übergeben. Wir können den Rückruf (componentConfig) aufrufen, um die Konfigurationen zu übergeben, wobei das Objekt componentConfig von der loadComponent oder einem anderen Loader verwendet werden kann.

  • loadComponent(name, componentConfig, callback)- Diese Funktion löst das viewModel und den Vorlagenteil der Konfiguration in Abhängigkeit von der Konfiguration auf. Wir können Callback (Ergebnis) aufrufen, um das Viewmodel / Template-Paar zu übergeben, wobei das Objektergebnis durch die folgenden Eigenschaften definiert wird.

    • template- Erforderlich. Array von DOM-Knoten zurückgeben.

    • createViewModel(params, componentInfo)- Optional. Gibt das viewModel-Objekt zurück, abhängig davon, wie die viewModel-Eigenschaft konfiguriert wurde.

  • loadTemplate(name, templateConfig, callback)- DOM-Knoten werden mithilfe einer benutzerdefinierten Logik in einer Vorlage übergeben. Das Objekt templateConfig ist eine Eigenschaft der Vorlage aus einer ObjektkomponenteConfig. Rückruf (domNodeArray) wird aufgerufen, um ein Array von DOM-Knoten zu übergeben.

  • loadViewModel(name, templateConfig, callback) - Die viewModel-Factory wird in einer viewModel-Konfiguration unter Verwendung einer benutzerdefinierten Logik übergeben.