Knockout - 将样式应用于 Bootstrap Select 中的选定项目

Posted

技术标签:

【中文标题】Knockout - 将样式应用于 Bootstrap Select 中的选定项目【英文标题】:Knockout - applying styles to the selected item in a Bootstrap Select 【发布时间】:2019-03-27 14:06:37 【问题描述】:

所以这是在库之上堆积库,但我不确定还能做什么。

我们的应用程序有许多下拉元素,它们都是Bootstrap Select 对象。这些将 select 中的标准选项标签集替换为一系列复杂的其他元素,使您可以更好地控制子元素的样式并使它们可搜索。

这些对象中的大多数作为可重用组件存在,具有 html 视图和 Typescript ViewModel,与 Knockout 绑定在一起。

其中许多菜单在文本旁边都有图标。这由 optionsAfterRender 处理。这是一个例子。

查看:

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

视图模型:

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;

这很好。但是,由于 Bootstrap Select 对其中的项目进行样式设置的方式,该图标不会应用于当前选定的项目 - 它仅在用户单击菜单并弹出时显示。

现在,当然,我们也需要在当前选定的项目中显示图标。但我不知道如何让该元素绑定到它。由于 view-viewmodel 模式,我无法直接获取它。它似乎不在 optionsAfterRender 传递的节点中。

我怎样才能掌握它的样式?

编辑:很确定这是引导选择中的错误。提出了一个问题

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

【问题讨论】:

在被点击之前,其他 Bootstrap 样式是否应用于选择?听起来selectPicker() 在渲染之后被初始化并且缺少 css 绘制可能存在问题。 @Levidps 感谢您的关注。选择标签本身有一些类,由于简洁,我没有使用,但没有动态 我的想法更多的是selectPicker 替换了一些 HTML 结构,因此初始类很好 b/c 它们存在并且 html 在初始绘制时存在。我会很好奇,因为 HTML 结构是在渲染后添加的,它在最初的 CSS 绘制中丢失了。前任。 ` DOM > CSS > selectPicker > new HTML elements` 现在在用户点击选择之前不会出现新的 CSS 绘制。 @Levidps 嗯。我认为这是引导选择中的错误。已对项目提出问题github.com/snapappointments/bootstrap-select/issues/2129 【参考方案1】:

您可以尝试通过阻止选项的后处理来解决此问题:

    options 绑定替换为 select 元素中的 foreach 绑定,将每个 option 绑定到适当的 ko 绑定。 在对元素调用 selectpicker 之前,确保 selectPicker 绑定具有其 descendant bindings 绑定。 利润!

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>

【讨论】:

以上是关于Knockout - 将样式应用于 Bootstrap Select 中的选定项目的主要内容,如果未能解决你的问题,请参考以下文章

Knockout.js v2.3.0 错误“您不能将绑定多次应用于同一元素”

在 Knockout 样式绑定中使用 CSS3 变量

Knockout JS,如何在更改可观察数组中的值时更改样式属性

CSS 样式在刷新后显示,然后在 Knockout 中不可见

Knockout.js - 封装视图模型并从外部隐藏它们

带有 Knockout 的 jsFiddle 适用于 IE 11 而不是 Chrome