在 knockout.js 中从外部主视图模型调用函数

Call function from outside master view model in knockout.js

我看过 similar topics,但是 none 他们使用的结构与我完全相同。

我正在使用多个视图模型,我通过创建一个 MasterModel 函数来处理它,稍后我将其作为参数传递给 applyBindings

基本上是这样的:

var MasterModel = function(){
    this.user = new UserViewModel();
    this.department = new DepartmentViewModel();
}

ko.applyBindings(MasterModel);

现在,我希望能够从 Javascript 访问我的一个视图模型中的函数,但我遇到了问题。

如果我将 applyBindings 更改为这个,我设法调用了 viewmodel 函数:

var mm = new MasterModel();
ko.applyBindings(mm);

mm.user.sayHi();

但后来我发现像下面这样的东西停止工作了:

<ul data-bind="foreach: department.list()">
     <li data-bind="text: department.getDemo($data)"></li>
</ul>

Message: department is not defined

Reproduction online

正如你所看到的 here,它在使用 ko.applyBindings(MasterModel);

时完美运行

有什么解决办法吗?

您需要将 Knockout 指向正确的方向才能使用 department:

<li data-bind="text: $root.department.getDemo($data)"></li>

当您处于 foreach 循环中时,范围是您当前正在迭代的项目,而该项目(显然)没有 department 属性.

您需要使用 $root 来告诉 Knockout 它是您所指的根视图模型上定义的 department

Fiddle and Documentation

在 foreach 内部,您无法直接访问 department,因为 foreach 引入了自己的绑定上下文。您可以使用 $root$parent 访问您的 MasterModel:

<ul data-bind="foreach: department.list()">
   <li data-bind="text: $parent.department.getDemo($data)"></li>
</ul>

http://jsfiddle.net/qWmat/109/

A binding context is an object that holds data that you can reference from your bindings. While applying bindings, Knockout automatically creates and manages a hierarchy of binding contexts. The root level of the hierarchy refers to the viewModel parameter you supplied to ko.applyBindings(viewModel). Then, each time you use a control flow binding such as with or foreach, that creates a child binding context that refers to the nested view model data.

Read more