164

我想在我的 ViewModel 上使用一个属性来切换要显示的图标,而无需创建单独的逆计算属性。这可能吗?

<tbody data-bind="foreach: periods">
  <tr>
    <td>
      <i class="icon-search" data-bind="visible: !charted, click: $parent.pie_it"></i>
      <i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>
    </td>
  </tr>
</tbody>

我的 ViewModel 有一个属性 period 是月份数组,如下所示:

var month = function() {
    this.charted = ko.observable(false);
};
4

8 回答 8

286

在表达式中使用 observable 时,您需要将其作为函数访问,例如:

visible: !charted()

于 2012-04-11T21:58:14.510 回答
53

我同意 John Papa 的评论,即应该有一个内置hidden绑定。hidden专用绑定有两个好处:

  1. 更简单的语法,即。hidden: charted而不是visible: !charted().
  2. 资源更少,因为 Knockout 可以charted直接观察 observable,而不是创建一个computedto observe !charted()

hidden但是,创建绑定很简单,如下所示:

ko.bindingHandlers.hidden = {
  update: function(element, valueAccessor) {
    ko.bindingHandlers.visible.update(element, function() {
      return !ko.utils.unwrapObservable(valueAccessor());
    });
  }
};

您可以像使用内置visible绑定一样使用它:

<i class="icon-search" data-bind="hidden: charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>
于 2012-05-13T17:35:57.823 回答
10

这有点令人困惑,因为你必须这样做

visible:!showMe()

所以我做了

<span data-bind="visible:showMe">Show</span>
<span data-bind="visible:!showMe()">Hide</span>
<label><input type="checkbox" data-bind="checked:showMe"/>toggle</label>​

我的模型是

var myModel={
    showMe:ko.observable(true)
}
ko.applyBindings(myModel);    

​签入小提琴http://jsfiddle.net/khanSharp/bgdbm/

于 2013-01-04T17:29:02.513 回答
4

你可以使用我的switch/case绑定,其中包括case.visiblecasenot.visible.

<tbody data-bind="foreach: periods">
    <tr>
        <td data-bind="switch: true">
        <i class="icon-search" data-bind="case.visible: $else, click: $parent.pie_it"></i>
        <i class="icon-remove" data-bind="case.visible: charted, click: $parent.pie_it"></i>
        </td>
    </tr>
</tbody>

你也可以把它当作

        <i class="icon-search" data-bind="casenot.visible: charted, click: $parent.pie_it"></i>
        <i class="icon-remove" data-bind="case.visible: $else, click: $parent.pie_it"></i>
于 2012-08-28T20:40:33.650 回答
1

为了让绑定知道属性的变化,我复制了可见的绑定处理程序并将其反转:

ko.bindingHandlers.hidden = {
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var isCurrentlyHidden = !(element.style.display == "");
        if (value && !isCurrentlyHidden)
            element.style.display = "none";
        else if ((!value) && isCurrentlyHidden)
            element.style.display = "";
    }
};
于 2013-04-14T10:19:27.227 回答
0

免责声明:此解决方案仅用于娱乐目的。

ko.extenders.not = function (target) {
    target.not = ko.computed(function () {
        return !target();
    });
};

self.foo = ko.observable(true).extend({ not: null });

<div data-bind="text: foo"></div>     <!-- true -->
<div data-bind="text: foo.not"></div> <!-- false -->

<!-- unfortunately I can't think of a way to be able to use:
    text: foo...not
-->
于 2016-04-17T14:44:25.623 回答
0

关于如何使用与布尔可观察对象相反的问题,我遇到了同样的问题。我找到了一个简单的解决方案:

var ViewModel = function () {
var self = this;

// When program start, this is set to FALSE
self.isSearchContentValid = ko.observable(false);


self.gatherPlacesData = function () {

   // When user click a button, the value become TRUE
   self.isSearchContentValid(true);

};

现在在你的 HTML 上你应该这样做

<p data-bind = "visible:isSearchContentValid() === false"> Text 1</p>
<p data-bind = "visible:isSearchContentValid"> Text 2</p>

当程序启动时,只有“Text1”可见,因为“false===false 为 TRUE”,而 Text2 不可见。

假设我们有一个按钮,它在点击事件时调用gatherPlacesData。现在 Text1 将不可见,因为“true === false is FALSE”并且 Text 2 仅可见。

另一种可能的解决方案可能是使用计算的 observable,但我认为对于一个如此简单的问题来说这是一个过于复杂的解决方案。

于 2018-12-07T19:30:19.993 回答
-1

也可以像这样使用隐藏

 <div data-bind="hidden: isString">
                            <input type="text" class="form-control" data-bind="value: settingValue" />
                        </div>
于 2017-05-31T08:04:42.163 回答