【问题标题】:Knockout style binding with three options具有三个选项的淘汰赛风格绑定
【发布时间】:2017-09-21 00:23:30
【问题描述】:

好的,所以我已经广泛使用 KO 样式绑定来显示用户输入数据的内联验证,并且效果很好。这是我的绑定之一:

data-bind='style: {backgroundPosition: ! currentRegistry().title() || !$root.currentRegistry().clientLogin()  ? "top" : "bottom"}

我遇到的麻烦是我想做这样的绑定,除了在第二个样式绑定上,如果 if 语句的计算结果为 false,我希望它返回到由设置的任何背景位置之前的绑定,而不是仅仅回到“底部”:

data-bind='style: {backgroundPosition: ! currentRegistry().title() || !$root.currentRegistry().clientLogin()  ? "top" : "bottom"}, style: {backgroundPosition: currentRegistry().title() && $root.currentRegistry().clientLogin() && ! $root.hasRegImage()  ? "20px" : "bottom"}'

换句话说,对于第二个绑定,我想说的是 style: {backgroundPosition: if stuff ? "THIS"} 否则不改变样式。希望这是有道理的,任何使这种情况发生的提示或指示将不胜感激!谢谢。

编辑:

虽然 RodneyTrotter 的解决方案无疑是获得相同功能的更优雅的方法,但我确实从一位同事那里学到了一种方法,该方法完全符合我的要求。我没有意识到你可以让每个属性都有条件,又名:

data-bind='style: {backgroundPosition: ! $root.currentRegistry().clientLogin() || ! $root.currentRegistry().title()  ? "top" :  (! $root.hasRegImage()  ? "20px" : "bottom")}'>

【问题讨论】:

    标签: binding knockout.js styles


    【解决方案1】:

    我会使用 css 绑定来实现这一点(注意:您可能需要调整 css 类的顺序才能达到预期的结果)

    HTML

    <div id='myElement'
        data-bind='css: {
            'foo': !currentRegistry().title() || !$root.currentRegistry().clientLogin(), 
            'bar': currentRegistry().title() && $root.currentRegistry().clientLogin() && ! $root.hasRegImage()
        }'>
        Hello, i am the div content.
    </div>
    

    CSS

    #myElement{
        background-position: bottom;
    }
    
    #myElement.foo {
        background-position:top;
    }
    
    #myElement.bar {
        background-position:20px;
    }
    

    【讨论】:

    • 我相信这是最优雅和正确的方式。
    【解决方案2】:

    不是 100% 确定这完全回答了您的问题,但这也是有效且非常有帮助的:

    'style': someCondition ? {'max-height': '100px'} : {}

    如果条件不满足,允许您不理会样式。


    另外,如果你使用组件,你可以调用

    'style': $component.getStyling($data)

    然后在getStyling 中执行一些多行 if 语句逻辑来构造包含样式的对象。

    同样适用于css 绑定。

    【讨论】:

      【解决方案3】:

      即使您已经接受了答案,我也想添加一个补充内容。我认为“关注点分离”是您在继续使用 Knockout 时要牢记的一个重要概念。

      通常认为最好的做法是将逻辑保留在视图模型中,将样式保留在 CSS 中,并且将它们都保留在绑定/html 之外。有几个好处,但主要是它使代码更清晰更易于维护。 Rodney 的回答让你朝着正确的方向迈出了一大步。

      就您的原始帖子而言,您希望将函数添加到您的视图模型中,以便让您的逻辑脱离绑定。例如,

      var viewModel = {
          backgroundStyle : function($root){
              return !$root.currentRegistry().clientLogin() || 
                  !$root.currentRegistry().title()  ? 
                  "top" :  
                      (! $root.hasRegImage()  ? "20px" : "bottom");
          }
      }
      

      然后您的绑定将简单地写成:

      <div data-bind="style : {backgroundPosition : backgroundStyle($root)}"></div>
      

      还有一步

      当然,我们已经将逻辑移出绑定,但现在我们已经在逻辑中获得了样式。又一次分离 ala Rodney 的回答,我们有...

      #myElement{
          background-position: bottom;
      }
      
      #myElement.foo {
          background-position:top;
      }
      
      #myElement.bar {
          background-position:20px;
      }
      

      视图模型为

      var viewModel = {
          decideClassName : function($root){
              return !$root.currentRegistry().clientLogin() || 
                  !$root.currentRegistry().title()  ? 
                  "foo" :  (! $root.hasRegImage()  ? "bar" : "");
          }
      }
      

      我们的绑定变成了

      <div data-bind="css : decideClassName($root)}"></div>
      

      我还应该指出,这种类型的动态 CSS 类名绑定仅在 Knockout 2.2.0 或更高版本中可用as per Steven Sanderson's blog


      以这种方式保持您的代码井井有条并“将关注点分开”可以帮助您轻松发现错误、进行更改、与团队合作,并且可能最重要的是可以引导您做出良好的实施决策。我最近helped someone on the Google group 如果他们的视图模型中有逻辑而不是绑定,他们会很容易找到答案。

      希望这些信息对您有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-25
        • 2013-05-04
        • 2013-12-06
        • 2013-03-18
        • 2014-03-07
        • 2013-02-04
        • 2015-08-31
        相关资源
        最近更新 更多