是否可以将数据绑定绑定到布尔型ViewModel属性的取反(“!”)?


162

我想在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具有一个属性周期,它是一个月数组,如下所示:

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

3
@Niko:这并不是一个重复的问题。这个问题你指的已经是OP知道是可能的,为什么它需要数据绑定可观察到的否定,而是奇迹被称为像函数。这个问题的操作人员首先不知道该怎么做,显然也没有找到其他问题。我很高兴在这里找到这个问题-这主要归功于其描述性标题。
奥利弗

Answers:


281

在表达式中使用可观察对象时,您需要像以下函数一样对其进行访问:

visible: !charted()


33
也许我们应该做一个隐藏的绑定:)我们启用和禁用。
约翰·帕帕

文档是否对此表示不同意见,还是我完全误解了此页面:knockoutjs.com/documentation/css-binding.html
Devil的拥护者

没关系,我想“ isSevere”不是一个可观察的东西,而是一个普通的旧财产,因此我很困惑。
魔鬼的代言人

3
使用!charted时,您会得到![Function]。[Function]是真实的,![Function]变为false,如果使用该语法,则始终为false。jsfiddle.net/datashaman/E58u2/3
datashaman 2014年

1
他们实际添加hidden的结合V3.5.0
咧嘴

53

我同意约翰·帕帕(John Papa)的意见,即应该有内置hidden绑定。专用hidden绑定有两个好处:

  1. 更简单的语法,即 hidden: charted代替visible: !charted()
  2. 资源较少,因为淘汰赛可以charted直接观察可观察对象,而不是创建computed观察对象!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>

9
这并没有对我没有回报的工作return !ko.utils.unwrapObservable(valueAccessor());
穆罕默德ATAS

感谢@MehmetAtaş-我已hidden根据您的评论更正了绑定。(顺便说一句,当我最初发布此消息时,我在我的项目中使用CoffeeScript。当有意返回时,CoffeeScript的语法没有使它变得明显。)
Dave

9

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

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/


4

您可以使用我的开关/大小写绑定,其中包括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>

我刚刚意识到这是一个老问题,但希望这对某人有用。
Michael Best

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 = "";
    }
};

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
-->

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不可见。

假设我们有一个按钮,该按钮在click事件上调用collectPlacesData。现在,Text1将不可见,因为“ true === false为FALSE”,而Text 2仅可见。

另一个可能的解决方案可能是使用可计算的可观察到的方法,但是,我认为对于如此简单的问题而言,这是一种过于复杂的解决方案。


-1

也可以这样使用隐藏

 <div data-bind="hidden: isString">
                            <input type="text" class="form-control" data-bind="value: settingValue" />
                        </div>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.