【问题标题】:Changing Knockout value bindings based on dynamic field visibility根据动态字段可见性更改 Knockout 值绑定
【发布时间】:2014-05-06 02:20:37
【问题描述】:

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

这就是我想要实现的目标。使用 KnockoutJS,我有一个 标签绑定到使用文本绑定计算的 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 属性会起作用,但它没有。可能有一种更简单的方法来解决这个问题,我愿意接受建议。

【问题讨论】:

  • 我不是 100% 清楚你想要达到的目标。如果您尝试支持接受/取消,那么这可能会有所帮助。 knockmeout.net/2011/03/… 我使用它非常成功,如果您接受更改,新值只会推送到 observable。

标签: jquery knockout.js


【解决方案1】:

这将完美运行


                                                                                 .               
<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();
        }
    });
});

【讨论】:

  • 这看起来与我提供的答案基本相同。您也可以在绑定中使用 chkNameChange observable 来执行以前的名称/名称的东西,而不是需要添加 jQuery 处理程序。
  • @RPNiemeyer 是的,交上 computed() 会很好。我认为在您的回答中,您将“新”模型变量绑定到相同“原始”表单INPUTs。我认为这是一个错误......不管是否检查,它不会被原来的 3 个输入卡住吗?
  • 变量都是从原始值初始化的。从那时起,它们将拥有自己的生命,并分别与输入绑定。
  • 这是一个很酷的把戏......无论哪种方式都是美丽的答案......毕竟你是淘汰赛之神 :-) 只是想知道这是否是 OP 希望从原始每个重置值点击它的时间?... @beaudetious:那是你想要的吗?或者您是否希望INPUTs 的第二个“新”集记住它们的值/您在其中输入的任何内容?
【解决方案2】:

您尝试做的最简单的方法可能是添加一个 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/

【讨论】:

  • 我喜欢你的回答,因为 a) 它干净简单,b) jsfiddle 链接有助于看到它的实际效果。我将尝试将其合并到我的代码中,看看它是如何工作的。感谢您的帮助(当然还有其他回复)。
  • @beaudetious 我认为这个答案有问题 ==> RPNiemeyer 将他的“新”模型变量绑定到 same“原始”表单 INPUTs,而不是的“新”形式输入。我认为这是一个错误......不管是否检查,它不会被原来的 3 个输入卡住吗?
  • @fd2g - 这些值只是从原始提供的值初始化的。从那时起,它们将拥有自己的生命,并分别与输入绑定。当有人检查这是更改名称时,这些值将默认为原始值。
  • 这是一个很酷的把戏......无论哪种方式都是美丽的答案......毕竟你是淘汰赛之神 :-) 只是想知道这是否是 OP 希望从原始每个重置值点击它的时间?... @beaudetious:那是你想要的吗?或者您是否希望INPUTs 的第二个“新”集记住它们的值/您在其中输入的任何内容?
  • @fd2g - 它们只是从原始值初始化,不会在每次单击复选框时重置。
【解决方案3】:

您可以根据您的复选框清理 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]);
             }
         }
     });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2018-03-13
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多