2012-04-11 61 views
145

我想使用我的ViewModel属性来切换显示哪个图标,而不创建逆的单独计算属性。这可能吗?是否有可能将数据绑定可见到布尔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> 

我的视图模型有一个属性周期是一个月的数组,像这样:

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

@Niko:这不是一个真正的重复问题。你提到的问题的OP已经知道**可以将可观察数据的否定与数据绑定,但是为什么需要像函数那样调用它。这个问题的OP在这里并不知道如何去做,显然没有找到其他问题。我很高兴我在这里发现了这个问题 - 这主要归功于它的描述性标题。 – Oliver 2013-05-14 11:32:47

回答

251

当在表达式中使用可观察到的,你需要访问它像一个功能:

visible: !charted()

+30

也许我们应该做一个隐藏的绑定:)我们已启用和禁用。 – 2012-04-11 23:21:23

+0

文档是否不同意这个,或者我完全误解了这个页面:http://knockoutjs.com/documentation/css-binding.html – 2013-06-15 20:17:49

+0

没关系,我猜“isSevere”不是一个可观察的,而是一个普通的旧属性,因此我的困惑。 – 2013-06-15 20:19:30

48

我与约翰爸爸的意见都认为应该有一个内置hidden绑定。专用hidden绑定有两个好处:

  1. 更简单的语法,即。 hidden: charted而不是visible: !charted()
  2. 较少的资源,因为Knockout可以直接观察到可观察的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());' – 2013-03-31 17:31:02

+0

谢谢@MehmetAtaş - 我更正了'隐藏'绑定您的评论。 (顺便说一下,我在我的项目中使用CoffeeScript的原始时间,当返回是故意的时候,CoffeeScript的语法并不明显) – Dave 2013-10-30 05:05:34

3

你可以使用我的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> 
+0

我刚刚意识到这是一个老问题,但希望这对于有人。 – 2012-08-28 20:44:00

8

它有点混乱,因为你必须做

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/

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

也可以使用隐藏这样的:

<div data-bind="hidden: isString"> 
          <input type="text" class="form-control" data-bind="value: settingValue" /> 
         </div> 
相关问题