在同一屏幕上淘汰两个视图模型

时间:2016-11-16 02:10:28

标签: javascript jquery knockout.js

我正在尝试在同一页面上创建登录表单和注册表单。 所以要这样做,我需要两个视图模型。我创建它们如下。

在我的页面上,我有两个单独的div,名为" login-form"和"注册表格"。

我正在尝试将每个视图模型应用到相应的DIV。

注意,我绑定了几个具有相同名称的字段,因为数据来自MVC模型。

@Html.TextBoxFor(x => x.EmailAddress, new { @class = "form-control", @placeholder = "Your Email Address", @type = "email", data_bind = "value: EmailAddress" })

该行出现在两个DIV中,但每个div都分配了一个单独的视图模型(或者我相信)。

<script type="text/javascript">

    var loginViewModel = function () {

        var self = this;

        EmailAddress = ko.observable("");
        Password = ko.observable("");

        EnableLogin = ko.computed(function () {
            if (self.EmailAddress() != "" && self.Password() != "")
                return true;
            return false;
        })
    }

    var registerViewModel = function () {

        var self = this;

        EmailAddress = ko.observable("");
        Password = ko.observable("");
        PasswordRetype = ko.observable("");
        TimeZoneID = ko.observable(0);

        EnableRegister = ko.computed(function () {
            if (
                    self.EmailAddress() != ""
                    && self.Password() != ""
                    && self.PasswordRetype() != ""
                    && self.Password() == self.PasswordRetype()
                    && self.TimeZoneID() > 0
                )
                return true;
            return false;
        })
    }

    ko.applyBindings(loginViewModel, $("#login-form"));
    ko.applyBindings(registerViewModel, $("#register-form"));

</script>

但是,当我在登录表单的电子邮件文本框中更新电子邮件地址时,该值也会分配给登录表单文本框。所以两个控件都以某种方式绑定。

但是,当我在注册表单中编辑电子邮件地址时,它不会在登录表单中更新。所以它似乎是单向的。

我正在做什么?如何将两个单独的div绑定到正确的视图模型?

2 个答案:

答案 0 :(得分:1)

ko.applyBindings中的第二个参数必须是您要绑定的实际DOM节点。目前,您正在尝试绑定到一个无法工作的jQuery选择器。

来自documentation

  

或者,您可以传递第二个参数来定义要搜索数据绑定属性的文档的哪个部分。例如,ko.applyBindings(myViewModel,document.getElementById(&#39; someElementId&#39;))。这会将激活限制为具有ID someElementId及其后代的元素,如果您希望拥有多个视图模型并将每个视图模型与页面的不同区域相关联,这将非常有用。

要使其工作,要么将选择器更改为vanilla JS,要么使用jQuery选择器中的实际DOM元素:

ko.applyBindings(loginViewModel, document.getElementById('login-form'));
ko.applyBindings(registerViewModel, $("#register-form")[0]);

答案 1 :(得分:0)

您可以使用ko.applyBindings的第二个参数。第二个参数告诉knockout绑定viewModel的位置。请查看here以获取更多信息。

  

第一个参数说明要使用的视图模型对象   它激活的声明性绑定

     

或者,您可以传递第二个参数来定义哪个部分   要搜索数据绑定属性的文档。例如,   ko.applyBindings(myViewModel,   的document.getElementById( 'someElementId'))。这限制了   激活ID为someElementId及其后代的元素,   如果您想拥有多个视图模型并关联,这非常有用   每个页面都有不同的区域。

因此,在这种情况下,您将有2个applyBindings调用。

另一种方法是将两个viewModel包含到更高的viewModel中。 像:

var mainViewModel = function(){
    this.loginModel = new loginViewModel();
    this.registerModel = new registerViewModel();
}

然后,您只需对每个特定with使用divs绑定即可访问loginModelregisterModel