使用attr绑定动态命名data- *属性的数据绑定

时间:2014-12-03 00:28:26

标签: javascript knockout.js

我发现了几个类似的问题,但他们似乎都没有完全解决这个问题。

我尝试根据'标记列表向元素添加属性。每个标签都是一个组的一部分。该组将是属性名称,标签将全部包含在值中。

基本上,我想执行与此类似的东西:

<ul data-bind="foreach: Options">
  <li>
    <a href="#" 
       data-bind="text: $data, 
                  attr: { 'data-' + $parent.Name : $data, 
                          'data-multiselect': $parent.IsMultiSelect.toString(), 
                          'rel': $parent.Name }">
    </a>
  </li>
</ul>

代码的重要部分是attr: { 'data-' + $parent.Name : $data ...

我已经尝试了各种方法来完成这项工作,例如预先确定属性名称,计算它们,调用函数等,但是淘汰只是不会处理它们。

2 个答案:

答案 0 :(得分:2)

我认为这里有一个自定义绑定。像这样:

&#13;
&#13;
ko.bindingHandlers.customDataAttr = {
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
      var key = valueAccessor().name;
      var val = valueAccessor().val;
      element.setAttribute(key, val);
      
      // see that it's been set:
      console.log(element);
    }
};

var ViewModel = function() {
  var self = this;
  self.Options = ['A', 'B', 'C'];
  self.Name = ko.observable("my-name");
  self.IsMultiSelect = 'false';
  
  self.dataAttrName = ko.computed(function(){
    return 'data-' + self.Name();
  });
};

ko.applyBindings(new ViewModel());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<ul data-bind="foreach: Options">
  <li>
    <a href="#" class="x"
       data-bind="text: $data, 
                  customDataAttr: { val: $data, name: $parent.dataAttrName() },
                  attr: { 'data-multiselect': $parent.IsMultiSelect.toString(), 
                          'rel': $parent.Name }">
    </a>
  </li>
</ul>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

一种方法是创建一个使用动态属性构建对象的函数:

self.createTagAttribute = function(tag, value) {
    var attrs = {};
    attrs[tag] = value;
    return attrs;
};

在你的装订中:

<li><a href="#" data-bind="
    text: $data, 
    attr: ko.utils.extend(
        $root.createTagAttribute($parent.Name, $data), 
        {'data-multiselect': $parent.IsMultiSelect.toString(), 'rel': $parent.Name}
    )"></a></li>

或者,如果你想保持你的绑定清洁(并且你觉得在道德上可以扩展Object原型),你可以添加以下内容:

Object.prototype.add = function(key, value) {
    this[key] = value;
    return this;
};

(应该放在ko.applyBindings之前)

在此之后,您可以执行以下操作:

<a href="#" 
   data-bind="text: $data, 
              attr: { 'data-multiselect': $parent.IsMultiSelect.toString(), 
                      'rel': $parent.Name }.add('data-' + $parent.Name, $data)">