最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Knockout.js changing colour of <option> when using 'options' binding? - Stack Overflo

programmeradmin0浏览0评论

Is it possible to alter the styling (using 'style' or 'css' binding) of a select list's option element when using the 'options' binding on a select list? Or can this only be done by using a 'foreach' on the select list and altering the styling for each ?

I have this in code:

<select id="ponents-select" size="4" name="ponents-select"
                        data-bind=" options: binedComponents, 
                                    optionsText: 'displayName', 
                                    optionsValue: 'id', 
                                    value: chosenComponent"></select>

but if I append style: {color: isDefault() === true ? 'black' : 'red'} then the entire list is coloured Red if isDefault returns false.

Is the only way to achieve this to code it this way:

<select id="ponents-select" size="4" name="ponents-select"
                        data-bind="foreach: binedComponents">
    <option data-bind="value: id, text: displayName, style: {color: isDefault() === true ? 'black' : 'red'}"></option>
</select>

Or is there some form of Knockout.js wizardry that I am not aware of?

Thanks!

Is it possible to alter the styling (using 'style' or 'css' binding) of a select list's option element when using the 'options' binding on a select list? Or can this only be done by using a 'foreach' on the select list and altering the styling for each ?

I have this in code:

<select id="ponents-select" size="4" name="ponents-select"
                        data-bind=" options: binedComponents, 
                                    optionsText: 'displayName', 
                                    optionsValue: 'id', 
                                    value: chosenComponent"></select>

but if I append style: {color: isDefault() === true ? 'black' : 'red'} then the entire list is coloured Red if isDefault returns false.

Is the only way to achieve this to code it this way:

<select id="ponents-select" size="4" name="ponents-select"
                        data-bind="foreach: binedComponents">
    <option data-bind="value: id, text: displayName, style: {color: isDefault() === true ? 'black' : 'red'}"></option>
</select>

Or is there some form of Knockout.js wizardry that I am not aware of?

Thanks!

Share Improve this question edited Mar 27, 2019 at 15:28 rwcorbett asked Apr 11, 2013 at 19:01 rwcorbettrwcorbett 4735 silver badges12 bronze badges 4
  • There aren't any wizardry options out there that I'm aware of. The default options binding handler only emits what is absolutely necessary the get the required semantics. And setting the color of each of the options was not a configurable setting. You could rewrite the handler to add those options. Possibly set the styles after the controls are rendered? – Jeff Mercado Commented Apr 11, 2013 at 19:10
  • 1 No there is no direct support for this in the KO options binding. But I think your second example with the manual foreach is the simplest solution for this problem. – nemesv Commented Apr 11, 2013 at 19:17
  • If you're going to be doing anything like this more than just this one time, you're better off creating your own binding handler, using options as a guide, e.g. optionsWithColor – Chris Pratt Commented Apr 11, 2013 at 21:39
  • 1 For anyone looking for this option, check out this question - stackoverflow./questions/25491607/… – Nick Commented Sep 24, 2014 at 13:03
Add a ment  | 

4 Answers 4

Reset to default 2

To expand on Thomas Wiersema's answer, the way you'd want to approach handling that on a per-row basis is something like:

<select id="ponents-select" size="4" name="ponents-select"
                    data-bind="foreach: binedComponents">
<option data-bind="value: id, text: displayName, style: {color: getColorFor.call(null, $data) }"></option>
</select>

then, in JavaScript, attach a function to your parent object like so (I'm making some assumptions, of course, like your parent object being called vm and isDefault belonging to a binedComponent):

vm.getColorFor = function(ponent) {
    return ponent.isDefault() === true ? 'black' : 'red';
}

If you're not sure what call does, check out bind vs apply vs call

I hope that helps -- let me know if I can elaborate!

To answer your question, yes that is the best way I believe.

with the code style: {color: isDefault() === true ? 'black' : 'red'} you bind(add) a style to the associated DOM element. In this case the whole <select> tag. Not a <option> tag like you want. That's why your entire list changes color.

Take a look at the knockoutjs docs for more info about style binding.

Try the 'optionsAfterRender' Binding which in this case works fine. http://jsfiddle/cZRJN/243/

var viewModel = function() {
  
  this.binedComponents = ko.observableArray([{
displayName: 'item1',
id: 1,
isDefault:true
  }, {
displayName: 'item2',
id: 2,
isDefault:false
  }, {
displayName: 'item3',
id: 3,
isDefault:true
  }]);
  
  OptionsAfterRender = (option, item) => {
    
    ko.applyBindingsToNode(option, {style: { color: item.isDefault ? 'red' : 'black'}}, item);
};
  
  
  this.chosenComponent= ko.observable(1);
}

ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare./ajax/libs/knockout/3.4.1/knockout-min.js"></script>
<link href="https://maxcdn.bootstrapcdn./font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>

<select id="ponents-select" size="4"  name="ponents-select"
                    data-bind=" options: binedComponents, 
                                optionsText: 'displayName', 
                                optionsValue: 'id', 
                                value: chosenComponent,
                                  optionsAfterRender:OptionsAfterRender
                                "></select>
                                    
                                    

To add up the what has already been said, there is one feature of Knockout that I find get's overlooked a lot and is very handy in these situations: $index. For example, I am making a list where I want the first option in the list to be black and the rest to be red. So I can just modify what you have as your second option like so:

<select id="ponents-select" size="4" name="ponents-select" data-bind="foreach: binedComponents"> <option data-bind="value: id, text: displayName, style: {color: $index === 0 ? 'black' : 'red'}"></option> </select>

Or if you want to alternate colors just use a modulus check.

<select id="ponents-select" size="4" name="ponents-select" data-bind="foreach: binedComponents"> <option data-bind="value: id, text: displayName, style: {color: $index % 2 === 1 ? 'black' : 'red'}"></option> </select>

发布评论

评论列表(0)

  1. 暂无评论