2016-06-11 6 views
1

Ich arbeite durch einige - interessante - Code, den ich nicht geschrieben habe, und stieß auf ein RequireJS-Modul, das eine KnockoutJS-Instanz für die Anwendung zu initialisieren scheint. KnockoutJS: Was macht Aufruf applyBindings ohne Argumente tun?

define([ 
    'ko', 
    './template/engine', 
    'knockoutjs/knockout-repeat', 
    'knockoutjs/knockout-fast-foreach', 
    'knockoutjs/knockout-es5', 
    './bind/scope', 
    './bind/staticChecked', 
    './bind/datepicker', 
    './bind/outer_click', 
    './bind/keyboard', 
    './bind/optgroup', 
    './bind/fadeVisible', 
    './bind/mage-init', 
    './bind/after-render', 
    './bind/i18n', 
    './bind/collapsible', 
    './bind/autoselect', 
    './extender/observable_array', 
    './extender/bound-nodes' 
], function (ko, templateEngine) { 
    'use strict'; 

    ko.setTemplateEngine(templateEngine); 
    ko.applyBindings(); 
}); 

Dieser Code ruft ko.applyBindings()ohne eine Ansicht Modell. Ich bin sehr neu zu knockout, aber alle die Tutorials, die ich gesehen habe, müssen Sie applyBindings ein ViewModel-Objekt übergeben.

Wie funktioniert der Aufruf applyBindings ohne Parameter genau?

Mein Endziel hier ist herauszufinden, wie diese Anwendung (Magento 2, wenn jemand neugierig ist) Knockout verwendet, um Dinge zu rendern, also bin ich auf der Suche nach Gründen ein Knockout-Entwickler könnte so etwas tun.

+0

Es sieht so aus, als wäre es in Ordnung, nur $ root und $ data werden nicht gesetzt. http://stackoverflow.com/questions/14903650/is-it-safe-to-call-ko-applybindings-without-any-parameters – skalpin

+0

@skalpin Ich fürchte, ich weiß nicht, was das bedeutet.Es ist mein Verständnis, dass Sie ein View-Modell brauchen, damit alles auf der Seite mit Knockout passiert. Ist das nicht korrekt? –

+1

yup @AlanStorm als ko ist mv'VM' - Sie brauchen ein ViewModel, wenn Sie nach '2-way' Bindung suchen (ich hoffe, Sie wissen). applyBinding erledigt die Aufgabe, ko zu aktivieren, wenn Sie viewModel als ersten Parameter übergeben, und gut seine Binds-Ansicht mit viewModel und behält die Änderungen in view & vm intact bei. Probe zum Spielen http://jsfiddle.net/LkqTU/30363/ –

Antwort

1

über einige Kommentare hier und zusätzliche Forschung, konnte ich die Antwort finden, die ich suchte.

Mein Fehler war zu denken ko.applyBindings() Hauptaufgabe war es, ein View-Modell (Javascript-Objekt) mit der Ansicht (HTML-Seite) zu verbinden. Während das ist ein von applyBindings 'Jobs, applyBindingsauch startet das Rendern der Ansicht (HTML-Seite). In Knockouts Welt bedeutet das Rendern der Ansicht, dass (mindestens?) Die HTML-Seite nach data-bind Attributen gescannt und diese Attribute verarbeitet werden.

Von selbst wäre die Verarbeitung der data-bind Attribute ohne Daten sehr nützlich. Wenn die von Ihnen verwendete Anwendung jedoch benutzerdefinierte Bindungen erstellt hat (wie in this tutorial zu sehen ist), gibt es keine Beschränkung auf das, was applyBindings tun kann. In meinem speziellen Fall hat Magento 2 eine benutzerdefinierte Bindung namens scope, die (über einige andere Mechanismen) Daten für einen bestimmten Knotenkontext bindet.

1

Die meisten der Knockout-Funktionalität macht keinen Sinn ohne ein Viewmodel, aber das macht es nicht erforderlich. Sie können in the source sehen, dass nichts bricht, wenn Sie Parameter keine Viewmodel übergeben: es setzt nur den Bindungskontext als undefined:

function getBindingContext(viewModelOrBindingContext) { 
    return viewModelOrBindingContext && (viewModelOrBindingContext instanceof ko.bindingContext) 
     ? viewModelOrBindingContext 
     : new ko.bindingContext(viewModelOrBindingContext); 
} 

Ein paar Beispiele, die ich denken kann, warum man würde applyBindings ohne Viewmodel:

  • Injizieren statischen Templates
  • Anbringen Methoden Ereignis-Listener, die im globalen Kontext sind

Ich muss allerdings zugeben, dass diese ein wenig gekünstelt fühlen ... Ich weiß wirklich nicht, warum der Code, den Sie gezeigt haben tut ...

window.logClick = function(data, event) { 
 
    console.log("Click"); 
 
}; 
 

 
ko.applyBindings();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<div> 
 
    <div data-bind="template: 'header-template'"></div> 
 

 
    <button data-bind="click: logClick">click listener in window</button> 
 
</div> 
 

 

 

 
<script id="header-template" type="text/html"> 
 

 
    <h1>A header inserted by template</h2> 
 
    
 
</script>