通过css绑定,knockout.js结合dynamic和静态类

在knockout.js中,我们可以使用静态类的css绑定

<div data-bind="css: {'translucent ': number() < 10}">static dynamic css classes</div> 

和dynamic

 <div data-bind="css: color">static dynamic css classes</div> 

我已经尝试http://jsfiddle.net/tT9PK/1/结合它的东西

 css: {color, translucent: number() < 10} 

同时获得dynamic类color和静态translucent ,但我得到一个错误。 有没有办法做到这一点?

你可以通过css属性添加dynamic类,然后通过attr属性添加静态类

 <div data-bind="attr: { 'class': color }, css: { 'translucent': number() < 10 }"> static dynamic css classes </div> 

确保将任何预定义的类添加到此绑定attr: { 'class': color }

我通过将css绑定为css2来解决了这个问题。

  ko.bindingHandlers['css2'] = ko.bindingHandlers.css; 

通常情况下,您不能在data-bind属性中使用相同的绑定处理程序两次,所以这允许我执行以下操作:

 <div data-bind="css: color, css2: { 'translucent': number() < 10 }">static dynamic css classes</div> 

我不能确定我是否仍然喜欢这个,或@Alexksey的答案,但如果您有多个dynamic类添加,这可能是唯一的select。

正确…并启动你更进一步,检查出这个修改。

http://jsfiddle.net/Fv27b/2/

在这里,你会看到,不仅我们结合了这些选项,而且还完全创build了我们自己的绑定……这不仅导致了这个视图模型的可移植扩展,而且还导致了您可能拥有的任何视图模型你的项目…所以你只需要写一个这个!

 ko.bindingHandlers.colorAndTrans = { update: function(element, valAccessor) { var valdata = valAccessor(); var cssString = valdata.color(); if (valdata.transValue() < 10) cssString += " translucent"; element.className = cssString; } } 

为了调用它,你只需要将它作为一个新的数据绑定属性,并且可以包含尽可能多的(或者尽可能less的)选项。 在这个特定的条件下,我可能刚刚提供了$ data,但是如果你想要一个可重用的选项,你需要更具体的数据types作为参数,而不是所有的视图模型可能具有相同的属性。

 data-bind="colorAndTrans: { color: color, transValue: number }" 

希望这不仅仅是回答你的问题!

你最好的select可能不是把它们结合起来。 而是使用视图模型的计算属性将它们组合成可以dynamic绑定的单个属性。 这样,你也可以避免把数字()<10绑定到你的视图,这是更清洁无论如何。

像这样,例如:

 viewModel.colorAndTrans = ko.computed(function () { var cssString = viewModel.color(); if (viewModel.number() < 10) { cssString += " translucent" } return cssString; }); 

看到这个工作的例子: http : //jsfiddle.net/tT9PK/4/

如果你真的进入了复杂的造型案例,只是积累在计算的属性。 你可以像Alex提到的那样做,或者更具可读性:

 vm.divStyle = ko.computed(function() { var styles = []; if (vm.isNested()) styles.push('nested'); if (vm.isTabular()) styles.push('tabular'); else styles.push('non-tabular'); if (vm.color()) styles.push(vm.color()); return styles.join(' '); }); 

主要的缺点是你将视图定义的一部分移到视图模型中,应该更独立。 另一种方法是把上面的所有逻辑都作为一个普通的js函数调用,让knockout评估它。

更多的select:

类似于使用计算的build议,可以内联expression式:

 <div data-bind="css: [color(), (number() < 10 ? 'translucent' : 'notTranslucent')].join(' ')">static dynamic css classes</div> 

作为特定于此案例的自定义绑定处理程序的替代方法,您可以创build一个采用混合css规范数组并将其传递给原始css处理程序的程序:

 <div data-bind="cssArray: [color, {translucent: number() < 10}]">static dynamic css classes</div> 

处理程序:

  ko.bindingHandlers.cssArray = { update: function (element, valueAccessor, allBindingsAccessor, data, context) { var arr = ko.unwrap(valueAccessor()); for (var i=0; i<arr.length; ++i) { var wrapped = function () { return ko.unwrap(arr[i]) }; ko.bindingHandlers.css.update(element, wrapped, allBindingsAccessor, data, context); } } } 

小提琴演示

通过计算属性名称(对于FF> 34,Chrome,Safari> 7.1 ),此问题有更好的解决scheme:

 <div data-bind="css: { [color]: true,'translucent': number() < 10 }"> static dynamic css classes </div> 

color是一个string值的属性。

如果color的值是可观察的,那么我们需要在可观察的更新之前清除类名。 如果我们不这样做,那么每次更改都会添加另一个类,而不会删除前一个类。 这可以很容易地手动完成,但是我为那些感兴趣的人写了一个扩展。

 ko.extenders.css = function(target, value) { var beforeChange; var onChange; //add sub-observables to our observable target.show = ko.observable(true); beforeChange = function(oldValue){ target.show(false); } onChange = function(newValue){ target.show(true); } target.subscribe(beforeChange, null, "beforeChange"); target.subscribe(onChange); return target; }; 

有了这个扩展器,你的JavaScript代码将如下所示:

 function MyViewModel() { this.color = ko.observable("red").extend({ css: true }); this.number = ko.observable(9) }; 

而你的标记就是这么简单:

 <div data-bind="css: { [color()]: color.show(),'translucent': number() < 10 }"> static dynamic css classes </div> 

我有一个代码笔演示这种技术: http : //codepen.io/USIUX/pen/WryGZQ

我也提交了一个淘汰赛的问题,希望有一天,自定义扩展将不是必要的: https : //github.com/knockout/knockout/issues/1990

好的问题,问题似乎是绑定的css不认为混合的两种, color(): color() != ''不起作用(会很好)。

我喜欢@ Simon_waver的回答方法,简单实用。

也许在这个问题的时候不支持(Idk),但与当前淘汰赛也结合了类作品: data-bind="css: computed"

 viewModel.computed = ko.pureComputed(function() { return viewModel.color() + (viewModel.number() < 10 ? ' translucent' : ''); });