【问题标题】:How to bind css class inside custom binding如何在自定义绑定中绑定 css 类
【发布时间】:2015-11-13 22:36:09
【问题描述】:

我创建了一个自定义绑定以用作颜色选择器。

<ul data-bind="colorPicker: selcol"></ul>

它创建了 10 个内联 div,每个 div 代表其他颜色。当我单击一个 div 时,颜色被选中。我在分配 'selected; 时遇到问题;选择 div 的 css 类。我尝试在自定义绑定中使用 css 绑定,但这不起作用。它只选择即使在选择其他 div 后仍保持选中状态的初始 div。

请查看示例:http://jsfiddle.net/zbkkzdsp/Jbvvq/

感谢您的帮助。如果您对我的代码有任何提示或 cmets,请告诉我。我是淘汰赛的新手,我会抓住机会了解更多信息。

【问题讨论】:

  • 我没有在那个小提琴中看到任何代码,只是结果。知道发生了什么吗?
  • Jsfiddle 这些天很有趣。同时使用codepen.io
  • 是的,即使是最简单的小提琴我也遇到了麻烦。最终使用 jsbin.com

标签: knockout.js ko-custom-binding


【解决方案1】:

似乎您在自定义绑定中使用计算值做了很多花哨的事情,所以我建议为您的颜色创建视图模型。

首先为每种颜色定义一个视图模型:

var ColorModel = function(options) {
  var self = this;

  // Keep a reference to the parent picker for selection
  self.picker = options.picker;

  // The CSS value of the color
  self.color = ko.observable(options.color || 'transparent');

  // A flag denoting whether this color is selected
  self.selected = ko.observable(options.selected || false);

  // This will be called when the corresponding color link is clicked
  // Note that we're not doing any event binding with jQuery as with your custom binder
  self.select = function() {
    self.picker.selectColor(self); 
  };
};

然后是颜色选择器本身的视图模型:

var ColorPickerModel = function() {
  var self = this;

  // The list of all colors
  self.colors = ko.observableArray([]);

  self.addColor = function(color) {
    var newColor = new ColorModel({
        picker: self,
        color: color
    });

    self.colors.push(newColor);
    return newColor;
  };

  // Called by individual colors
  self.selectColor = function(colorModel) {
    // Deselect the current color so we don't select two
    var current = self.selected();
    if (current) {
      current.selected(false);
    }

    // Mark the color as selected - KO will do the rest
    colorModel.selected(true);

    // Remember this color as the selected one to deselect later
    self.selected(colorModel);
  };

  // Create at least one default color
  var transparent = self.addColor('transparent');

  // Keep track of the selected color - set to transparent by default
  self.selected = ko.observable(transparent);
  transparent.select();
};

然后将您的 HTML 视图绑定到您的选择器视图模型:

<div id="color-picker">
  <div data-bind="foreach: colors">
    <a href="#" data-bind="
       style: { 'background-color': $data.color }, 
       css: { 'selected': selected }, 
       click: select"></a>
  </div>
  <div>
    Selected color: <span data-bind="text: selected().color"></span>
  </div>    
</div>

然后把它们绑在一起:

var pickerDiv = document.getElementById('color-picker'),
    picker = new ColorPickerModel();

// Add some colors
picker.addColor('red');
picker.addColor('blue');
picker.addColor('green');
picker.addColor('orange');
picker.addColor('purple');
picker.addColor('black');

// Bind Knockout
ko.applyBindings(picker, pickerDiv);

// Add more colors - the view will update automatically
picker.addColor('pink');

这是一个工作示例:http://jsbin.com/izarik/1/edit

【讨论】:

  • 谢谢。您的解决方案非常有效,但我的目标是尽可能多地打包自定义绑定以供以后重用。我想在不同的站点上放置许多这样的颜色选择器,这样使用单个绑定处理程序就很容易实现。
  • 在这种情况下,如果您已经在自定义绑定中使用 jQuery 事件来处理点击,为什么不直接使用它来分配“选定”类?例如。每次点击时,addClass('selected')。也就是说,如果您已经没有按预期使用 KO,为什么还需要 KO 绑定?
  • 我设法准备了工作示例:jsfiddle.net/uvc2b/2 我不确定它是否没有任何可能导致性能问题或其他问题的错误。 @Vlad 为什么使用自定义绑定没有按预期使用 KO?
  • @Eori 抱歉,我并不是说使用自定义绑定不是“kosher KO”,我的意思是在自定义绑定中使用 jQuery 事件并不是“KO 方式”据我了解。例如,在您最新的小提琴中,您无需为每种颜色添加任何 KO 绑定,因为您已经使用 jQuery 管理它们的类。我的(个人)规则是,如果我使用自定义绑定(我广泛使用),绑定应该只添加行为,而不是注入新的 DOM 元素(因为绑定已经发生,处理程序的 init 方法甚至执行)。
  • 如果您从绑定处理程序告诉 KO 您的绑定处理程序控制后代绑定,则可以在绑定处理程序中创建子元素。见knockoutjs.com/documentation/…。如果您确实仍然需要在子元素中进行一些绑定,那么您可以在绑定处理程序中转身并使用 ko.applyBindingsToDescendants(有关文档,请参见同一 KO 页面)。
猜你喜欢
  • 2013-02-12
  • 2012-03-10
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 2012-02-09
  • 2013-03-27
  • 2011-07-28
  • 2023-03-03
相关资源
最近更新 更多