Подтвердить что ты не робот

Доступ viewModel в функции javascript вне viewModel scope

Мне интересно, могу ли я получить доступ к основному представлению модели knockout.js из метода, выходящего за пределы области viewModel. Возьмите этот пример:

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

Ответ 1

Вы всегда можете получить к нему доступ, просто сохранив свою модель просмотра в переменной, к которой вы можете получить доступ, модуль и выявление шаблонов модулей хороши, но вы можете просто сохранить его в объекте, который не будет конфликтовать с другими именами ('my' здесь):

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

У вас была правильная идея, вам просто нужно взять элемент как аргумент вашей функции щелчка и передать целевое свойство в ko.dataFor или 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());
    });
});​

Вместо того, чтобы использовать jQuery для привязки события click, вы всегда можете использовать привязку кликов к нокауту, которая передает текущие данные модели как первый параметр и событие в качестве второго параметра (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());
  };
}

В вашем html ($ root - ваша модель базового представления, вам не понадобится, если ваша функция clickedOnEmployee была на ваших объектах Employee):

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