Skip to main content
 首页 » 编程设计

knockout.js之在 viewModel 范围之外的 javascript 函数中访问 viewModel

2024年09月07日21emanlee

我想知道是否可以从 viewModel 本身范围之外的方法访问 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'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? 
  }); 
} 

请您参考如下方法:

您始终可以通过将 View 模型存储在您可以访问的变量中来访问它,module and revealing module patterns很好,但是您可以将其存储在不会与其他名称冲突的对象中(此处为“我的”):

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

您的想法是正确的,您只需将元素作为 click 函数的参数并将 target 属性传递给 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绑定(bind)点击事件,你总是可以使用 the Knockout click binding ,它将当前模型数据作为第一个参数传递,将事件作为第二个参数传递( 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 是您的基本 View 模型,如果您的 clickedOnEmployee 函数在您的 Employee 对象上,则不需要它):
<ul data-bind="foreach: employees"> 
    <li> 
        <span data-bind="text: name"></span> 
        <button data-bind="click: $root.clickedOnEmployee">show</button> 
    </li> 
</ul>