如何在大型SPA中嵌入基于knockout.js的组件?

时间:2012-12-08 09:47:09

标签: javascript knockout.js single-page-application

我目前正在尝试使用SPA,我的第一个应用程序的结构大致遵循Mikowski / Powell即将出版的书Single Page Web Applications中描述的模式:该应用程序由相互嵌套的模块组成。一个根模块具有一个或多个子模块,每个子模块可以具有其自己的一个或多个子模块。为了将子模块添加到DOM,父模块为子连接自己的标记提供了一个(jQuery-)元素。除此之外,模块或多或少完全隔离,它们的功能与SPA的其余部分无关。每个模块都驻留在自己的文件中,并使用require.js解析依赖关系(该书手动导入它们)。

现在我想使用knockout.js渲染一些模块,但我对ko很新,所以我想知道:想象一下顶层模块附加了几个子模块。它使用knockout.js进行绑定,而其中一个子模块也执行绑定,但另一个子模块没有。每个人当然都拥有自己的模型数据。

  1. 如果我在父级和子级中应用ko-bindings(仅限于相应的容器元素),当父级的标记实际包含子级的标记时,它们是否会以某种方式发生干扰?
  2. 如何在这样的情况下实现require.js依赖项解析?
  3. 可能很好地说明问题的一个例子是“选项卡式面板”:父级有几个选项卡,并使用knockout来确定当前可见的选项卡。每个选项卡本身都是一个模块,它本身可以具有任意复杂的标记/功能,因此应该封装在自己的文件/模块中。

1 个答案:

答案 0 :(得分:6)

您不希望在父元素上调用ko.applyBindings,然后在其中一个子元素上调用ko.applyBindings。元素将被绑定两次,尽管在大多数情况下你只会得到错误,因为孩子可能会尝试绑定不同的上下文。

几个选择:

1 - 如果元素不重叠,则可以调用ko.applyBindings(viewModelOne, document.getElementById("one")); ko.applyBindings(viewModelTwo, document.getElementById("two")); 并指定第二个参数,该参数是用作根元素的DOM元素。这看起来像是:

var ViewModel = function() {
   this.tabs = ko.observableArray();
   this.selectedTab = ko.observable();
};

2 - 在您的问题中,似乎Knockout将管理选项卡以及每个选项卡的内容,其中各个选项卡可能是子元素。一种选择是创建一个包含子视图模型的整体视图模型,如:

ko.applyBindings

"标签"然后,对象可以包含自己的视图模型。它可能类似于:http://jsfiddle.net/rniemeyer/PctJz/

3 - 此处描述了另一种替代方案:http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html。此技术允许您将视图模型绑定到整个页面,但随后将调用{{1}}并将DOM元素作为第二个参数分别绑定到区域。