Javascript 使用ViewModel构造函数完成虚拟合成

Javascript 使用ViewModel构造函数完成虚拟合成,javascript,knockout.js,constructor,durandal,Javascript,Knockout.js,Constructor,Durandal,我有一些奇怪的功能,使用3对视图/视图模型进行虚拟淘汰组合 autoAttendant.js define(['durandal/app', 'viewmodels/settings/autoAttendant/menu'], function(app, Menu){ return function() { var self = this; self.attendant = ko.observable(); self.activate

我有一些奇怪的功能,使用3对视图/视图模型进行虚拟淘汰组合

autoAttendant.js

define(['durandal/app', 'viewmodels/settings/autoAttendant/menu'], function(app, Menu){

    return function() {
        var self = this;

        self.attendant = ko.observable();

        self.activate = function() {
            self.autoAttendant(new Menu());
        };
    };
});
autoAttendant.html

<div id="content_pane" class="pushed_right">
    <div class="content_box">
        <h1>Attendant</h1>

        <!-- ko compose: 'viewmodels/settings/autoAttendant/menu' --><!--/ko-->

    </div>
</div>
menu.html

<div class="list">
    <div class="box_item master">
        <!-- html content -->
    </div>
    <!-- ko foreach: { data: menuItems } -->
        <!-- ko compose: 'viewmodels/settings/autoAttendant/menuItem' --><!--/ko-->
    <!-- /ko -->
</div>
menuItem.html

<div class="level">
    <div class="box_item clickable">
        <!-- html content -->
    </div>
</div>

它们一起表示设置中的一个页面,该页面显示菜单和该菜单的子项

菜单和菜单项必须与助理视图/视图模型分离,因为菜单本身是递归的,并且菜单项可以使用自己的菜单项链接到子菜单

问题出现在第二个
ko compose
console.log
出现3次,前2次在menu.js中向MenuItem构造函数显示正确的传递参数:

val:val1标签:label1活动:未定义

在最后的
控制台.log
打印输出中,已传递的参数将被覆盖,如下所示:

val:label:Object{model:“viewmodels/settings/autoAttendant/menuItem”,bindingContext:L.b.z,activeView:null}
活动:未定义


为什么会发生这种情况?

在对源代码进行彻底研究和(不止)一点实验后,以下方法奏效了:


运行foreach循环之前,是否尝试检查菜单项?接下来的想法是:如果menuItems本身没有问题,那么这就是Durandal源代码中的
ko.compose
。设置断点有助于澄清问题。我在
ko foreach
前后放置了带有menuItems to json的span,并且menuItems的格式正确。因此,在切换到组合菜单项上下文时,这些值会丢失或被覆盖。现在您已经明白了这一点。已经有ko.observable
menuItems
保存所有
新的MenuItem(…)
,因此定义视图就是所需要的。我甚至不知道Durandal有那么聪明,谢谢分享。
define(['durandal/app'], function(app) {
    var menuItem =  function(val, label, active) {
        var self = this;

        console.log('val:', val, 'label:', label, 'active:', active); // purely for testing purposes

        var _val = val || 'default_val',
            _label = label || 'default_label',
            _active = active || false;

        self.val = ko.observable(_val);
        self.label = ko.observable(_label);
        self.active = ko.observable(_active);
    };
    return menuItem;
});
<div class="level">
    <div class="box_item clickable">
        <!-- html content -->
    </div>
</div>