即使为 false,也输出 Knockout 可观察值

Output Knockout observable value even if false

我正在使用一个名为 this.expanded 的 Knockout observable 来处理是否渲染某些 HTML,并且还使用 aria-expanded 属性中的值。

<button data-bind="attr: { 'aria-expanded': expanded }">
<!-- ko if : expanded -->
   <div>...</div>
<!-- /ko -->

在这两种情况下使用我的变量 expanded 的问题是我注意到当 expanded 为假时,我根本没有得到 aria-expanded 属性的输出。

// When expanded is true:
<button aria-expanded="true"></button>

// When expanded is false:
<button></button>

// What I want:
<button aria-expanded="false"></button>

expanded 为 false 时,如何仅使用 false 仍然输出属性?

我尝试创建一个辅助变量来检查 observable 并将其转换为字符串:

this.expandedStatus = this.expanded().toString()

但我注意到如果以这种方式使用 expandedStatus 似乎不再 update/observe。

您可以简单地将 aria-expanded 属性绑定到可观察对象的 toString() 值,而无需引入新的可观察对象。看看下面的例子:

function Test() {
  var self = this;
  self.expanded = ko.observable(false);
  self.toggleExpanded = function() {
    self.expanded(!self.expanded());
  }
}

ko.applyBindings(new Test());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<button data-bind="attr: { 'aria-expanded': expanded().toString() }">
<!-- ko if : expanded -->
   <span>...</span>
<!-- /ko -->
</button>

<p>
  <button data-bind="click: toggleExpanded">Toggle</button>
</p>

我最终找到了一个非常简单的解决方案,就是通过三元设置 aria-expanded:

<button data-bind="attr: { 'aria-expanded': expanded() ? 'true' : 'false' }">

另一种方法是将绑定处理程序与 jQuery 一起使用,这样更方便:

<button data-bind="isAriaExpanded: expanded ">
<!-- ko if : expanded -->
   <div>...</div>
<!-- /ko -->

...

ko.bindingHandlers.isAriaExpanded= {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        jQuery(element).attr('aria-expanded',false);//initially setting to false
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
      value = valueAccessor();
      valueUnwrapped = ko.unWrap(value);
      jQuery(element).attr('aria-expanded',valueUnwrapped);//whenever the expanded() is changed automatically aria-expanded attribute gets updated
    }
};