1

好的,所以我已经广泛使用 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")}'>
4

3 回答 3

2

我会使用 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;
}
于 2013-06-03T23:01:01.850 回答
2

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

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

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


此外,如果您使用的是组件,您可以调用

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

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

同样适用于css绑定。

于 2017-09-20T16:23:30.427 回答
1

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

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

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

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>

我还应该指出,根据 Steven Sanderson 的博客,这种类型的动态 CSS 类名绑定仅在 Knockout 版本 2.2.0 或更高版本中可用。


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

我希望这个信息是有帮助的!

于 2013-06-04T02:39:02.473 回答