Knockout JS - 将 css class 绑定到一个元素

Knockout JS - bind css class to an element

我想实现动态 class 出价,它应该根据放入该字段的变量分配和重新分配正确的 class。我遇到的问题是,当我引入函数 setRed(),然后 setWhite(),两种颜色 class 都被绑定,当然第一个 CSS class 被考虑.

我有一个绑定看起来像这样的元素:

<div data-bind='dxNumberBox: dxCustomCalc'></div>

到目前为止我做了elementAttrclassko.observable();

self.dxCustomCalc = {
    displayExpr: 'Name',
    keyExpr: 'Id',
    value: self.customCalc,
    //onValueChanged: function (e) {
    //    self.childFormName(e.component.option('selectedItem'));
    //},
    disabled: ko.computed(function () {
        return self.readOnly;
    }),
    elementAttr: {
        /*   class: "is-valid-nok"*/        /* - red*/
        /*class: "is-valid-onlyok"  */    /* -white */
        /*class: "is-required-empty",*/  /* - yellow */
        class: ko.observable(),
    }
};

并遍历元素:

function setRed() {
    self.dxCustomCalc.elementAttr.class("is-valid-nok");
    console.log("color changed to red")
}

function setWhite(){
    self.dxCustomCalc.elementAttr.class("is-valid-onlyok");
    console.log("color changed to white")
}

函数根据字段中的值执行。例如,如果值匹配,函数 setRed() 被触发。然后,如果值发生变化并且满足条件,则函数 setWhite() 被触发。 在订阅元素上执行两个函数后,我得到的结果是:

<div data-bind="dxNumberBox: dxCustomCalc" class="dx-numberbox is-valid-nok is-valid-onlyok">

执行完这两个函数我想要达到的结果是:

<div data-bind="dxNumberBox: dxCustomCalc" class="dx-numberbox is-valid-onlyok">

我会使用 class 绑定来根据可观察对象设置 CSS class。

你可以直接使用它

<div data-bind="dxNumberBox: dxCustomCalc, class: dxCustomCalc.cssClass">

或者您可以应用 class 绑定作为您的 dxCustomCalc 自定义绑定的一部分,使用 ko.applyBindingsToNode():

ko.bindingHandlers.dxNumberBox = {
  init: function(elem, valueAccessor, allBindings, viewModel) {
    const value = ko.unwrap(valueAccessor());
    ko.applyBindingsToNode(elem, {class: value.cssClass}, viewModel);
  }
};

function DxNumberBox() {
  this.dxCustomCalc = {
    cssClass: ko.observable("is-required-empty")
  };
  this.setRed = () => this.dxCustomCalc.cssClass("is-valid-nok");
  this.setWhite = () => this.dxCustomCalc.cssClass("is-valid-onlyok");
  this.setEmpty = () => this.dxCustomCalc.cssClass("is-required-empty");
}

const vm = new DxNumberBox();
ko.applyBindings(vm);
.is-valid-nok {
  background-color: red;
}

.is-valid-onlyok {
  background-color: white;
}

.is-required-empty {
  border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.js"></script>

<button data-bind="click: setRed">Red</button>
<button data-bind="click: setWhite">White</button>
<button data-bind="click: setEmpty">Empty</button>

<div data-bind="dxNumberBox: dxCustomCalc">
  Profit Information
</div>

<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

Functions are executed based on value in field.

.setRed() 这样的额外方法既笨重又不必要。将 cssClass 转换为计算的可观察对象,根据视图模型的状态计算 class 名称,例如

cssClass: ko.pureComputed(() => {
  var value = self.value().trim();
  if (value == '') return 'is-required-empty';
  if (value < 0) return 'is-valid-nok';
  return 'is-valid-onlyok';
});