【问题标题】:How to enable and disable an input field using knockout when there is a checkbox?有复选框时如何使用敲除启用和禁用输入字段?
【发布时间】:2015-10-21 16:46:07
【问题描述】:

我有一个复选框字段和一个输入字段 (endDate)。我想启用和禁用 endDate 取决于复选框值(选中复选框时,endDate 被禁用,反之亦然)。我的输入和复选框元素如下:

<input id="inUse" type="checkbox" data-bind="checked: inUse"/>
<input id="endDate" data-bind="datepicker: enDate, enable: enableEndDate"/>

启用结束日期:

self.enableEndDate = ko.computed(function(){
     return !inUse();
    }
});

页面加载时,取决于inUse 字段值,endDate 将被启用或禁用。当我取消选中inUse 时,endDate 将被启用。 现在我想在用户单击它时启用禁用的endDate,然后同时将inUse 的值更改为未选中。如何绑定这两种方式的过程?

【问题讨论】:

  • 您可以使用disable: inUse 作为您的结束日期。你真的不需要计算出来的。
  • 对,或者让你计算出来的return !self.inUse();
  • @JohnnyHK 如果我想启用 endDate 并在用户单击 endDate 输入框时取消选中 inUse 框怎么办?我也想保留之前的启用/禁用绑定。

标签: knockout.js


【解决方案1】:

您的要求是:

  • 如果用户单击inUse 复选框,文本框应启用或禁用,具体取决于复选框状态
  • 如果文本框被禁用,并且用户单击它,则应该启用文本框并选中复选框

首先,如果您禁用文本框,它不会抛出事件,因此无法知道用户何时单击它。因此,您需要使用readonly,而不是disabled。单击只读文本框时,会触发单击事件。

Knockout 没有只读绑定。您可以使用通用的attr 绑定,或者创建一个readonly 处理程序,这非常简单:

// Add new binding handler for readonly
ko.bindingHandlers['readonly'] = {
    'update': function (element, valueAccessor) {
        var value = !!ko.utils.unwrapObservable(valueAccessor());
        if(value !== element.readOnly)
            element.readOnly = value;
    }
};

这必须在加载敲除库之后和绑定视图模型之前运行。您可以将readonly 用作任何内置处理程序。

此外,您还可以修改 CSS 以明确禁用文本框,例如:

/* Make visible when the control is disabled */
input[readonly] {
    background-color: #EEE;
}

那么,接下来的故事就很简单了。这是视图模型和绑定:

var vm = (function() {
    var inUse = ko.observable(false);
    var endDate = ko.observable(null);
    var endDateClick = function() {
        console.log('Clicked!');
        if (!inUse()) inUse(true);
    };
    return {
        inUse: inUse,
        endDate: endDate,
        endDateClick: endDateClick
    }
})();

ko.applyBindings(vm);

这是对应的 HTML:

<input id="inUse" type="checkbox" data-bind="checked: inUse"/>
<input id="endDate" data-bind="value: endDate, readonly: !inUse(), click: endDateClick"/>

您可以在 this fiddle 中看到它的工作原理。或直接:

// Add new binding handler for readonly
ko.bindingHandlers['readonly'] = {
    'update': function (element, valueAccessor) {
        var value = !!ko.utils.unwrapObservable(valueAccessor());
        if(value !== element.readOnly)
            element.readOnly = value;
    }
};

var vm = (function() {
    var inUse = ko.observable(false);
    var endDate = ko.observable(null);
    var endDateClick = function() {
        console.log('Clicked!');
        if (!inUse()) inUse(true);
    };
    return {
        inUse: inUse,
        endDate: endDate,
        endDateClick: endDateClick
    };
})();

ko.applyBindings(vm);
/* Make visible when the control is disabled */
input[readonly] {
    background-color: #EEE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input id="inUse" type="checkbox" data-bind="checked: inUse"/>
<input id="endDate" data-bind="value: endDate, readonly: !inUse(), click: endDateClick"/>

【讨论】:

  • 非常感谢@JotaBe。唯一的问题是我的 endDate 从后端获取它的值。因此,当用户在输入框中单击时,我需要将值更改为 false,例如 endDateClick 函数中的 inUse('false') 。但它不起作用。如何将值更改为 false?
  • 请更准确地描述问题。我不知道您是否只需要更改 inUse “极性”(即将 true 更改为 false 或反之亦然)。如果您描述正确,我可以轻松地更改代码。你试过玩小提琴吗?你有什么问题吗?我真的很想帮助你,但我不清楚问题是什么。
  • 小提琴工作正常。但在我的项目中,我使用 ajax 调用获取数据(如 inUse 和 endDate)。所以我的 observables 在一个对象中:self.myObject.inUse() 和 self.myObject.endDate()。我不会像您在代码中所做的那样向他们传递任何价值。当我的 inUse 字段具有来自 ajax 调用的值(例如“true”)时,我了解一切,当点击绑定运行时,如何将值更改为 false?当我想将 inUse 的值更改为“true”时,我的问题在 endDateClick 函数中。
  • 还是很难理解你的问题。但我会尽力而为:如果问题是你不知道包含inUse 属性的对象是什么,ko viewmodels 中用作事件处理程序的函数可以接收 2 个参数,第一个是对象绑定到触发事件的元素。因此,如果您像这样修改我的小提琴中的处理函数:var endDateClick = function(obj),您可以检查obj 是一个包含inUse 和其他可观察属性的对象。如果这不是问题,请在您的 q 中添加一些代码或修改我的小提琴
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 2014-01-21
  • 2021-10-27
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多