2016-07-12 8 views
0

Wenn ich ein View-Modell mit Blick binden,Knockout js, Bindungskontext und View-Modell ist sehr verwirrend

html

<div data-bind="text: $data.name"></div> 

javascript

var viewModel = { 
    name: ko.observable('Steve') 
}; 

ko.applyBindings(viewModel); 

Die div den Namen Steve zeigt . Der Bindungskontext enthält die Eigenschaft $ data, sie bindet den Namen im viewModel, auf den sich $ data mit dem Element div bezieht. Ich verstehe das. Aber was ich nicht verstehe, ist, dass, wenn ich $ Daten in der Datenbindung im Div-Tag entferne, es immer noch funktioniert. Ohne $ data, bezieht sich der Name nicht auf eine Eigenschaft direkt im Bindungskontext namens "name", die nicht existiert? was passiert unter der Haube in dem Fall, wenn $ Daten nicht vorhanden sind?

+0

Der Bindungs ​​Kontext das Viewmodel-Objekt ist. $ data bezieht sich auch auf das viewModel, weshalb es möglich ist, $ data in Ihrem Datenbindungsattribut wegzulassen. –

+0

@MaheshWarrier. Der Bindungskontext für das Dokument ist ein Objekt, das spezielle Eigenschaften wie $ data, $ root enthält, wenn der Bindungskontext viewModel ist, dann sollte er diese Eigenschaften enthalten, was nicht der Fall ist. –

+0

Knockout fügt diese Eigenschaften zu Ihrem Ansichtsmodell hinzu, wenn Sie applyBindings aufrufen. Wenn Sie wirklich ins Detail gehen wollen, können Sie in den Quellcode schauen: http://knockoutjs.com/downloads/knockout-3.4.0.debug.js. Insbesondere sollten Sie sich die Funktion applyBindings –

Antwort

2

Es funktioniert, weil Knockout einen with Block verwendet. Ihre text Bindung der Rückgabewert wird nach innen eingewickelt:

"with($context){with($data||{}){return{" + bindingValue + "}}}"; 

Wie Sie in the source sehen können.

Dieser Codeabschnitt bedeutet, dass die Eigenschaften Ihres Ansichtsmodells zuerst durchsucht werden. Wenn eine Eigenschaft nicht vorhanden ist, prüft knockout, ob sie sich im Bindungskontext befindet.

Hier ist ein Beispiel, wie es irgendwie funktioniert:

var vm = { 
 
    vmProp: 'VMPROP' 
 
}; 
 

 
var bindingCtx = { 
 
    $ctxProp: 'CTXPROP', 
 
    $data: vm 
 
}; 
 

 
function log() { 
 
    with(bindingCtx) { 
 
    with($data) { 
 
     console.log(vmProp);  // Works 
 
     console.log($ctxProp);  // Also works 
 
     console.log($data.vmProp); // Also works 
 
    } 
 
    } 
 
} 
 

 
log();

+0

Das ist die Antwort, nach der ich suche. –

0

Nach documentation. Ihr ViewModel-Objekt im aktuellen Kontext wird auf das Body-Tag angewendet, wenn der 2. Parameter nicht in ko.applyBindings vorhanden ist. Es ist, weil Sie keinen 2. Parameter enthalten, der rootNode für applyBindings ist. Es bewirkt, dass $data auf body Tag angewendet wird. So können Sie Ihre viewModelproperties und functions überall in Ihrem body Tag verwenden.