Привязать массив к привязке стиля Knockout - PullRequest
0 голосов
/ 29 июня 2018

У меня есть наблюдаемый массив свойств css. Элементы такие:

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

Я хочу не использовать foreach для создания нескольких тегов <style>.

Мне нужно что-то, что может сделать что-то вроде этого:

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

Есть идеи?

1 Ответ

0 голосов
/ 29 июня 2018

Шаг 1: объединение массива свойств в один объект

Много способов сделать это, из которых я предпочитаю использовать Object.assign и синтаксис распространения:

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

Для других (более совместимых с браузером) способов, выполните поиск в Google / «Объединение массива объектов».

Шаг 2: Установка стилей

Судя по внешнему виду вашего свойства, вы используете пользовательские свойства css , которые, насколько я знаю, не поддерживаются по умолчанию style привязкой . ..

Вы можете написать быстрое пользовательское связывание, которое использует 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, которая не обновляет пользовательское свойство. Третий элемент использует пользовательскую привязку, обновляя как color, так и background-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>
...