Search code examples
knockout.js

Knockout.js indexed based color from array


Hello and thanks in advance.

I am building a custom component and I want to retrieve properties from a component array.

In the component viewModel:

graph.colors = ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"];

...and then in the template:

<div class="legend" data-bind="foreach: legend">
    <div class="item">
      <span class="box" data-bind="style: { 'background-color': $parent.colors[$index]}"></span>
      <span data-bind="text: $data"></span> <!-- works -->
      <span data-bind="text: $index"></span>  <!-- works -->
      <span data-bind="text: $component.colors[0]"></span> <!-- works -->
      <span data-bind="text: $component.colors[$index]"></span>  <!-- blank! -->
    </div>
  </div>

While the $index returns correct and $component.colors is well defined, the color is not returning.

Thanks!


Solution

  • The index is a function, when using it as text: index it is automatically unwrapped, it also works like that for observables. But when using it within an array index selector you should add the () so it reads:

    <span data-bind="text: $component.colors[$index()]"></span>

    const colors = ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"];
    
    ko.applyBindings();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    
    <ul data-bind="foreach: { data: [...Array(10).keys()], as: 'item' }">
      <li data-bind="text: colors[$index()]"></li>
    </ul>