在knockout.js中使用多个viewModel

时间:2013-02-21 01:21:26

标签: knockout.js

我想让我的淘汰赛脚本更有条理,而且,我想避免将两个功能命名为同一件事。所以我想知道是否可以将viewModel嵌套在同一个函数中(我保持简单):Fiddle

这是HTML

<p>First name: <strong data-bind="text: other.firstName">todo</strong></p>
<p>Last name: <strong data-bind="text: other.lastName">todo</strong></p>
<p>Full name: <strong data-bind="text: other.fullName">todo</strong></p>

和JS:

function AppViewModel() {
    var self = this;
    self.other = {
        firstName: ko.observable("Bert"),
        lastName: ko.observable("Bertington"),
        /*fullName: ko.computed(function(){
            return this.firstName + " " + this.lastName;
            }, this)*/

        }
}

这很好用,但如果我取消注释ko.computed它会崩溃。有没有办法以这种方式组织我的淘汰赛,为什么计算机崩溃,有没有办法编写ko.computed函数,以便它可以工作?

编辑:问题#2

如果我有任何形式的表格:

<form data-bind="submit: other.otherSubmit" data-ajax="false">
    <button type="submit">Submit</button>
</form>

我为提交添加了一个处理程序:

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
    function AppViewModel() {
        var self = this;
        self.other = new function(){     
            var self = this;
            self.firstName = ko.observable("Bert");
            self.lastName = ko.observable("Bertington");
            self.fullName = ko.computed(function(){            
                return self.firstName() + " " + self.lastName();
                });
            self.otherSumbit = function(){}
            }
    }

// Activates knockout.js
ko.applyBindings(new AppViewModel());

为什么错误控制台会返回此信息:

提交绑定的值必须是函数

4 个答案:

答案 0 :(得分:2)

可以试试这个:

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
    function AppViewModel() {
        var self = this;
        self.other = new function(){     
            var self = this;
            self.firstName = ko.observable("Bert");
            self.lastName = ko.observable("Bertington");
            self.fullName = ko.computed(function(){            
                return self.firstName() + " " + self.lastName();
                });        
            }
    }

// Activates knockout.js
ko.applyBindings(new AppViewModel());

答案 1 :(得分:1)

您的第一个案例中的问题是,在该上下文中,this引用了视图模型。在对象文字中,您的对象尚不存在,因此您无法以这种方式设置计算的可观察对象。在创建对象后,您必须将其添加到对象中。

要么像这样(这很难看):

function AppViewModel() {
    var self = this;
    self.other = {
        firstName: ko.observable('Bert'),
        lastName:  ko.observable('Bertington')
    };
    self.other.fullName = ko.computed(function() {
        return this.firstName() + ' ' + this.lastName();
    }, self.other);
}

或者像这样(正如你在第二个例子中所做的那样):

function AppViewModel() {
    var self = this;
    self.other = new function() {
        this.firstName = ko.observable('Bert');
        this.lastName = ko.observable('Bertington');
        this.fullName = ko.computed(function() {
            return this.firstName() + ' ' + this.lastName();
        }, this);
    };
}

当然,还有其他方法可以编写上述示例,但您明白我的观点。


在你的第二个例子中,你刚拼错了你的功能。在视图模型中,当您的视图具有otherSumbit时,它被命名为otherSubmit

答案 2 :(得分:0)

我用一种技术来组织我的VM使用淘汰赛:

//load view
    $.get(url, function(view){
        $("#content').html(view);
        ko.applyBindings(new myVM(), $('#content')[0]);
    })

答案 3 :(得分:0)

如果有人在寻找此类解决方案的解决方案,请尝试以下方法

Html View

    <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <div id="container1">
        <ul>
            <li >Container1 item</li>
            <!-- ko foreach: myItems -->
            <li>Item <span data-bind="text: $data"></span></li>
            <!-- /ko -->
        </ul>
    </div>

    <div id="container2">
        <ul>
            <li >Container2 item</li>
            <!-- ko foreach: myItems -->
                <li>Item <span data-bind="text: $data"></span></li>
            <!-- /ko -->
        </ul>
    </div>

    <script src="js/jquery-1.11.1.js"></script>
    <script src="js/knockout-3.0.0.js"></script>
    <script src="js/DataFunction.js"></script>
    <script src="js/Container1ViewModel.js"></script>
    <script src="js/Container2ViewModel.js"></script>

</body>
</html>

对于这个视图,我在两个单独的javascript文件中为id = container1和id = container2创建了两个视图模型。

Container1ViewModel.js

function Container1ViewModel()
{
    var self = this;
    self.myItems = ko.observableArray();
    self.myItems.push("ABC");
    self.myItems.push("CDE");

} 

Container2ViewModel.js

function Container2ViewModel() {
    var self = this;
    self.myItems = ko.observableArray();
    self.myItems.push("XYZ");
    self.myItems.push("PQR");

}

然后在这两个视图模型在DataFunction.js中注册为单独的视图模型

var container1VM;
var container2VM;

$(document).ready(function() {

    if ($.isEmptyObject(container1VM)) {
        container1VM = new Container1ViewModel();
        ko.applyBindings(container1VM, document.getElementById("container1"));
    }

    if ($.isEmptyObject(container2VM)) {
        container2VM = new Container2ViewModel();
        ko.applyBindings(container2VM, document.getElementById("container2"));
    }
});

像这样你可以为不同的div添加任意数量的viewmodel。但请确保不要为已注册的div内的div创建单独的视图模型。