将数组绑定到Knockout样式绑定

时间:2018-06-29 08:59:17

标签: javascript arrays knockout.js data-binding binding

我有一个CSS属性的observableArray。元素是这样的:

[{ "--border-color": "red" //(colorName = observable - colorValue = observable) ... }]

我想避免使用foreach创建多个<style>标签。

我需要可以做这样的事情:

data-bind="style: colorStyles"  //colorStyles = array mentioned above

有什么主意吗?

1 个答案:

答案 0 :(得分:1)

步骤1:将属性数组合并到单个对象中

许多方法可以做到这一点,我更喜欢使用Object.assign和传播语法:

const mergedStyle = Object.assign({}, ...colorStyles);

对于其他(与浏览器更兼容)的方式,google /搜索“合并对象数组”。

第2步:设置样式

从您的媒体资源名称的外观来看,您使用的是custom css properties,据我所知,default style binding不支持...

您可以编写一个快速的自定义绑定,该绑定在内部使用element.style.setProperty来添加支持:

ko.bindingHandlers.varStyle = {
  init: (el, va) => {
    ko.computed(() => {
      Object.entries(ko.unwrap(va()))
        .forEach(([prop, val]) => {
          el.style.setProperty(prop, val);
        });
    });
  }
}

请务必检查您的极端情况。

演示:

第一个元素呈现常规的,不变的<div>样式。第二个使用默认的style绑定,该绑定无法更新自定义属性。第三个元素使用自定义绑定,同时更新colorbackground-color

// Our style objects:
const allStyles = ko.observableArray([
  { "color": "white" },
  { "--my-color": "red" }
]);

const mergedStyle = ko.pureComputed(
  () => Object.assign({}, ...allStyles())
);

// Our custom binding
ko.bindingHandlers.varStyle = {
  init: (el, va) => {
    ko.computed(() => {
      Object.entries(ko.unwrap(va()))
        .forEach(([prop, val]) => {
          el.style.setProperty(prop, val);
        });
    });
  }
}

ko.applyBindings({
  myStyle: mergedStyle
});
div {
  --my-color: green;
  background: var(--my-color);

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<div data-bind="style: {}">Hello world</div>
<div data-bind="style: myStyle">Hello world</div>
<div data-bind="varStyle: myStyle">Hello world</div>