Knockout - applying styles to the selected item in a Bootstrap Select

馋奶兔 提交于 2019-12-11 09:48:31

问题


So this is piling libraries on top of libraries, but I'm not sure what else to do.

Our application has a number of drop-down elements all of which are Bootstrap Select objects. These replace the standard set of option tags inside the select with a complex series of other elements that give you much greater control over the styling of the children and make them searchable.

Most of these objects exist as reusable components with an HTML view and a Typescript ViewModel, bound together with Knockout.

A number of these menus have icons next to the text. This is handled with optionsAfterRender. Here's an example.

View:

<select
  data-bind="options: items, 
            value: selectedValue, 
            optionsText: 'value',
            optionsValue: 'id',
            selectPicker: {},
            optionsAfterRender: applyOptionAttributes">
</select>

ViewModel:

export default class SelectComponent {

selectedValue: KnockoutObservable<string>;
items: KnockoutObservableArray<SelectOption>

  constructor(koObservable: KnockoutObservable<string>) {
    // items fetched and bound
  }

  applyOptionAttributes(option: Node, item: SelectOption): void {
    ko.applyBindingsToNode(option, { attr: { "data-content": `<img src="${item.iconurl}" />`, title: item.value } }, item);
  }
}

interface SelectOption {
    value: string;
    id: string
    iconurl: string;
}

And this is fine. However, because of the way Bootstrap Select styles the items inside it, the icon is not applied to the currently selected item - it's only displayed when the user clicks on the menu and it pops up.

Now, of course, we have a requirement to display the icon in currently selected item too. But I don't know how to get that element to bind to it. I can't fetch it directly because of the view-viewmodel pattern. It doesn't seem to be among the nodes passed by optionsAfterRender.

How can I get hold of it to style it?

EDIT: pretty sure this is a bug in bootstrap-select. Have raised an issue

https://github.com/snapappointments/bootstrap-select/issues/2129


回答1:


You could try to fix this by preventing the post-processing of the options:

  1. Replace the options binding with a foreach binding in the select element, binding each option with the appropriate ko-bindings.
  2. Make sure the selectPicker binding has its descendant bindings bound before calling selectpicker on the element.
  3. Profit!

ko.bindingHandlers['selectPicker'] = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
      ko.applyBindingsToDescendants(bindingContext, element);
      $(element).selectpicker();
      return { controlsDescendantBindings: true };
    }
}

ko.applyBindings({
    selectedValue: ko.observable(3),
    options: [
      { id: 1, name: 'Mustard', dc: '<span class="badge badge-warning">Mustard</span>' },
      { id: 3, name: 'Ketchup', dc: '<span class="badge badge-danger">Ketchup</span>' },
      { id: 4, name: 'Relish', dc: '<span class="badge badge-success">Relish</span>' }
    ]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.3/css/bootstrap-select.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.3/js/bootstrap-select.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<select data-bind="selectPicker, value: selectedValue">
    <!-- ko foreach: options -->
    <option data-bind="text: name, attr: { value: id, 'data-content': dc }"></option>
    <!-- /ko -->
</select>


来源:https://stackoverflow.com/questions/52947292/knockout-applying-styles-to-the-selected-item-in-a-bootstrap-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!