根据动态字段可见性更改Knockout值绑定

时间:2014-05-06 02:20:38

标签: jquery knockout.js

我在这里设置了一个简单的示例:http://jsfiddle.net/YzKX9/5/

这就是我想要实现的目标。使用KnockoutJS,我有一个< span>使用文本绑定绑定到计算的observable的标记:

Full name: <span data-bind="text: fullName"></span>

加载表单时,值来自一组字段:

First Name: <input type="text" data-bind="value: firstName" /><br />
MI Name: <input type="text" data-bind="value: middleInitial" /><br />
Last Name: <input type="text" data-bind="value: lastName" /> 

但是,我有另一组隐藏的字段具有相同的绑定定义,我用一个复选框控制它们的可见性。当这些字段可见时,我希望这些字段控制计算的observable中的文本,并从初始字段集中删除数据绑定。

我完全不知道如何解决这个问题。我想可能从第一组字段中删除 data-bind 属性可行,但事实并非如此。这可能是一个更简单的方法,我愿意接受建议。

3 个答案:

答案 0 :(得分:2)

这将完美地工作


                                                                                 .               
<div id="result">  
  Fullname: <span id="fullName" data-bind="text: fullName"></span>
  <hr />
  <h3>
    Options
  </h3>
  <input type="checkbox" data-bind="checked: chkNameChange" id="chkNameChange" />Name change?
  <hr />
  <div id="sectionOne">
    <h3 id="headerSectionOne">
      Name
    </h3>
    First Name:<input type="text" data-bind="value: firstName" />
    <br />
    MI Name:<input type="text" data-bind="value: middleInitial" />
    <br />
    Last Name:<input type="text" data-bind="value: lastName" />
  </div>
  <hr />
  <div id="sectionTwo" style="display: none;">
    <h3>
      New Name
    </h3>
    First Name:<input type="text" data-bind="value: firstNameNew" />
    <br />
    MI Name:<input type="text" data-bind="value: middleInitialNew" />
    <br />
    Last Name:<input type="text" data-bind="value: lastNameNew" />
  </div>

然后你的JavaScript:

function EmployeeViewModel(firstName, lastName, middleInitial, firstNameNew, lastNameNew, middleInitialNew) {
    var self = this;

    self.chkNameChange = ko.observable(false);

    self.firstName = ko.observable(firstName);
    self.lastName = ko.observable(lastName);
    self.middleInitial = ko.observable(middleInitial);

    self.firstNameNew = ko.observable(firstNameNew);
    self.lastNameNew = ko.observable(lastNameNew);
    self.middleInitialNew = ko.observable(middleInitialNew);

    self.fullName = ko.computed(function () {
        if (!self.chkNameChange()){
            return self.lastName() + ", " + self.firstName() + " " + self.middleInitial();
        }
        else{
            return self.lastNameNew() + ", " + self.firstNameNew() + " " + self.middleInitialNew();
        }
    }, self);

}

var evm = new EmployeeViewModel("John", "Doe", "Q", "", "", "");
ko.applyBindings(evm);

$(document).ready(function () {
    $("#chkNameChange").live("click", function (event) {
        if ($("#chkNameChange").is(':checked')) {
            $("#headerSectionOne").text("Former Name");
            $("#sectionTwo").show();
        } else {
            $("#headerSectionOne").text("Name");
            $("#sectionTwo").hide();
        }
    });
});

答案 1 :(得分:1)

您尝试做的最简单的方法可能是添加一个observable来跟踪您是否正在进行名称更改。您可以将其绑定到您的复选框,控制第二组字段的可见性,并在计算中使用它。代码可能如下所示:

function EmployeeViewModel(firstName, lastName, middleInitial){
    this.firstName = ko.observable(firstName);
    this.lastName = ko.observable(lastName);
    this.middleInitial = ko.observable(middleInitial);

    this.newFirstName = ko.observable(firstName);
    this.newLastName = ko.observable(lastName);
    this.newMiddleInitial = ko.observable(middleInitial);

    this.isNameChange = ko.observable(false);

    this.fullName = ko.computed(function () {
        if (this.isNameChange()) {
            return this.newLastName() + ", " + this.newFirstName() + " " + this.newMiddleInitial();    
        }

        return this.lastName() + ", " + this.firstName() + " " + this.middleInitial();
    }, this);
}

您将对输入使用checked绑定,而不需要使用jQuery来处理更改。

小提琴:http://jsfiddle.net/rniemeyer/Jb79U/

答案 2 :(得分:0)

您可以清除 div元素的绑定,具体取决于您的复选框。 ko.cleanNode 方法将从DOM元素中删除绑定,您可以在干净的DOM节点上再次应用绑定。

<强> FIDDLE

function EmployeeViewModel(firstName, lastName, middleInitial){
    var self = this;
    self.firstName = ko.observable(firstName);
    self.lastName = ko.observable(lastName);
    self.middleInitial = ko.observable(middleInitial);

    self.fullName = ko.computed(function () {
        return self.lastName() + ", " + self.firstName() + " " + self.middleInitial();
    }, self);
}

var viewModel = new EmployeeViewModel("John", "Doe", "Q");
ko.applyBindings(viewModel);

$( document ).ready(function() {
     $("#chkNameChange").live("click", function (event) {                
         if ($("#chkNameChange").is(':checked')) {
             $("#headerSectionOne").text("Former Name");
             $("#sectionTwo").show();
             ko.cleanNode($("#sectionOne")[0]);
             if (ko.dataFor($("#sectionTwo")[0])) {
                  ko.applyBindings(viewModel,$("#sectionTwo")[0]);
             }
         }
         else{
            $("#headerSectionOne").text("Name");
             $("#sectionTwo").hide();

             ko.cleanNode($("#sectionTwo")[0]);
             if (ko.dataFor($("#sectionOne")[0])) {
                  ko.applyBindings(viewModel,$("#sectionOne")[0]);
             }
         }
     });
});