2012-05-17 13 views
33

Mi chiedo se posso accedere alla vista principale di knockout.jsModel da un metodo esterno all'ambito di viewModel. Prendete questo esempio:Accesso viewModello in funzione JavaScript all'esterno dell'ottica di modello

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? 
    }); 
} 

risposta

52

è sempre possibile accedere semplicemente memorizzando la ViewModel in una variabile è possibile accedere, il module and revealing module patterns sono belle, ma si può solo conservarlo in un oggetto che non sia in conflitto con altri nomi ('il mio' qui):

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

hai avuto l'idea giusta, non vi resta che prendere l'elemento come argomento alla funzione clic e passare la proprietà di destinazione per ko.dataFor o 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()); 
    }); 
});​ 

Invece di usare jQuery per legare l'evento click, si può sempre utilizzare the Knockout click binding, che passa i dati del modello corrente come primo parametro e l'evento come secondo parametro (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()); 
    }; 
} 

nel codice HTML (il $ radice è la sua opinione modello base, non avrebbe bisogno se la funzione clickedOnEmployee era in oggetti per i dipendenti):

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

Grazie per questo (corretto) risposta, ma mi chiedo se c'è ancora un modo per accedere alle informazioni fuori dal contesto solo per riferimento futuro? –

+1

ha aggiunto questi dettagli in primo piano, ko.dataFor e ko.contextPer solo il nodo dom, che è possibile osservare l'evento nella funzione del gestore. $ root sul risultato del contestoPer sarebbe il tuo modello di vista –