【问题标题】:Is it possible to data-bind visible to the negation ("!") of a boolean ViewModel property?是否可以对布尔 ViewModel 属性的否定(“!”)可见的数据绑定?
【发布时间】:2012-04-24 06:16:55
【问题描述】:

我想在我的 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);
};

【问题讨论】:

  • @Niko:这并不是一个重复的问题。您提到的问题的 OP 已经知道 可以对 observable 的否定进行数据绑定,但想知道为什么需要像函数一样调用它。这个问题的 OP 在这里首先不知道如何做到这一点,显然没有找到其他问题。我很高兴在这里找到了这个问题——这主要归功于它的描述性标题。

标签: knockout.js


【解决方案1】:

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

visible: !charted()

【讨论】:

  • 也许我们应该做一个隐藏绑定:) 我们已经启用和禁用。
  • 文档不同意这一点,还是我完全误解了这个页面:knockoutjs.com/documentation/css-binding.html
  • 没关系,我猜“isSevere”不是可观察的,而是普通的旧属性,因此我很困惑。
  • 使用 !charted 时,您将获得 ![Function]。 [Function] 是真实的, ![Function] 变为 false,如果您使用该语法,将始终为 false。 jsfiddle.net/datashaman/E58u2/3
  • 他们实际上在v3.5.0 中添加了hidden 绑定
【解决方案2】:

我同意 John Papa 的评论,即应该有一个内置的 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>

【讨论】:

  • 这对我来说没有回报return !ko.utils.unwrapObservable(valueAccessor());
  • 谢谢@MehmetAtaş - 我根据您的评论更正了hidden 绑定。 (顺便说一句,我最初发布此内容时在我的项目中使用 CoffeeScript。当有意返回时,CoffeeScript 的语法并不明显。)
【解决方案3】:

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

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

    您可以使用我的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>
    

    【讨论】:

    • 我刚刚意识到这是一个老问题,但希望这对某人有用。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        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,但我认为对于一个如此简单的问题来说这是一个过于复杂的解决方案。

        【讨论】:

          【解决方案8】:

          也可以像这样使用隐藏

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

          【讨论】:

            猜你喜欢
            • 2010-11-14
            • 1970-01-01
            • 2013-01-15
            • 2013-01-30
            • 1970-01-01
            • 2011-05-19
            • 1970-01-01
            • 2011-02-04
            • 2010-11-23
            相关资源
            最近更新 更多