2012-05-17 5 views
33

Ich frage mich, ob ich auf die knockout.js HauptansichtModel von einer Methode außerhalb des Bereichs des ViewModel selbst zugreifen kann. Nehmen Sie dieses Beispiel:Zugriff auf ViewModel in JavaScript-Funktion außerhalb von ViewModel Bereich

function Employee(data) { 
    var self = this; 
    ko.mapping.fromJS(data, {}, this); 
} 

function EmployeeViewModel() { 
    var self = this; 
    this.employees = ko.observableArray([]); 

    this.loadEmployees = function() { 
    var mappedEmployees= $.map(JSON.parse(data.value), function(item) { return new Employee(item) }); 
    self.employees (mappedEmployees); 
    } 
} 

// here's the part I'm curious about 
$(document).ready(function() { 
    ko.applyBindings(new EmployeeViewModel()); 

    $("#myLink").click(function() { 
    // is there some way to get back into the ko context here? 
    // like with ko.dataFor or ko.contextFor? 
    }); 
} 

Antwort

52

Sie immer es nur Ihr Viewmodel in einer Variablen zugreifen können durch Speicher Sie zugreifen können, die module and revealing module patterns sind nett, aber man kann es nur in einem Objekt speichern, die nicht mit anderen Namen in Konflikt steht (‚meine‘ hier):

my = { viewModel: new EmployeeViewModel() }; 
ko.applyBindings(my.viewModel); 

Sie hatte die richtige Idee, die Sie gerade das Element ergreifen müssen, um als Argument für Ihre Klick-Funktion und übergeben Sie die Zieleigenschaft zu ko.dataFor oder ko.contextFor (jsfiddle) :

$(document).ready(function() { 
    my.vm = new EmployeeViewModel(); 
    ko.applyBindings(my.vm); 
    $('button').on('click', function(e) { 
     alert('you clicked on employee ' + ko.contextFor(e.target).$data.name() + 
      ' also known as ' + ko.dataFor(e.target).name()); 
    }); 
});​ 

Stattdessen jQuery der Verwendung des Click-Ereignis zu binden, können Sie immer the Knockout click binding verwenden, die die aktuellen Modelldaten als erste Parameter übergeben und das Ereignis als zweiten Parameter (jsfiddle):

function EmployeeViewModel() { 
    var self = this; 

    // skipped some of your code 

    this.clickedOnEmployee = function(model, event) { 
    // assuming your Employee has a name observable 
    alert('You clicked on employee ' + model.name()); 
    }; 
} 

in Ihrem HTML (die $ root ist Ihre Basisansicht Modell, würden Sie brauchen es nicht, wenn Ihre clickedOnEmployee Funktion auf Ihrem Mitarbeiter Objekten sind):

<ul data-bind="foreach: employees"> 
    <li> 
     <span data-bind="text: name"></span> 
     <button data-bind="click: $root.clickedOnEmployee">show</button> 
    </li> 
</ul> 
+0

Vielen Dank für diese (richtige) Antwort, aber ich frage mich, ob es noch ist eine Möglichkeit, die Informationen aus dem Kontext heraus zu beziehen, nur für zukünftige Referenz? –

+1

hinzugefügt diese Details im Vordergrund, ko.dataFor und ko.contextFor nur brauchen den Dom-Knoten, den Sie mit Blick auf das Ereignis in Ihrer Handler-Funktion bekommen können. $ root für das Ergebnis von contextFor wäre Ihr View-Modell –