【问题标题】:Knockout custom binding how to identify which observable fired update?淘汰赛自定义绑定如何识别哪个可观察的触发更新?
【发布时间】:2017-03-02 08:52:10
【问题描述】:

我有一个自定义绑定,它依赖于两个 observable:dataselected。把它想象成一张精致的桌子。

在 html 中它被称为: <div data-bind="myComponent: {}, data: myData, selected: currentSelection"></div>

ko.bindingHandlers.myComponentupdate 函数在 myData 和/或 currentSelection 更改时触发。在 update 函数中,我如何确定哪个 observable 触发了它?因为如果 myData 发生变化,我必须重新渲染组件,而如果 currentSelection 发生变化,我只需要更新突出显示的元素。

Knockout : find out which observable triggerred computed 是唯一的解决方案吗?

感谢您的帮助!

【问题讨论】:

  • 我也不确定所引用解决方案的触发顺序。也就是说,是否保证.subscribe() 在绑定处理程序之前运行?

标签: knockout.js


【解决方案1】:

我不确定这是否被认为是“不好的做法”,但我经常通过在init 函数中添加自己的订阅来绕过update 方法...

这将允许您创建多个单独的订阅,这些订阅执行特定于dataselected 中的更改的行为。

认为这个方法让你负责处理额外的订阅,所以你可能想要做一些额外的内存泄漏检查..

在下面的示例中,您将看到一个只有 init 函数的自定义绑定。在init 中,我检索了另外两个绑定(在我的情况下leftright 将是dataselected 在你的情况下)。我为这些可观察值发生变化定义了两种不同的行为。在init 函数的末尾,我调用了这两个函数。

ko.bindingHandlers.myComponent = {
  init: function(element, valueAccessor, allBindings) {
    var changeLeftColor = function() {
      element.children[0].style.backgroundColor = randomColor();
    }
    
    var changeRightColor = function() {
      element.children[1].style.backgroundColor = randomColor();
    }
  
    var leftSub = allBindings.get("left").subscribe(changeLeftColor)
    var rightSub = allBindings.get("right").subscribe(changeRightColor);
    
    changeLeftColor();
    changeRightColor();
    
    // When knockout disposes the element (for example because 
    // it's in an `if` binding), dispose the subs.
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
      leftSub.dispose();
      rightSub.dispose();
    });
  }
}

ko.applyBindings({ left: ko.observable(0), right: ko.observable(0) });


// Utils
function randomColor() {
  return "#" + Array(6).fill().map(function() {
    return "0123456789ABCDEF"[Math.floor(Math.random() * 16)];
  }).join("");
}
div > div {
  display: inline-block;
  width: 40px;
  height: 40px;
  text-align: center;
  line-height: 40px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>


<div data-bind="myComponent, left: left, right: right">
  <div data-bind="text: left, click: left.bind(null, left() + 1)"></div>
  <div data-bind="text: right, click: right.bind(null, right() + 1)"></div>
</div>

【讨论】:

  • 完全正确的解决方案!谢谢。因此,update 方法似乎仅适用于琐碎的情况。还是我错了?
  • 对我来说,init / update 的分离更多是关于明确定义什么是您只想运行一次的初始化逻辑(例如添加事件侦听器)。我想补充一点,通常自定义绑定应该做 one 的事情。如果您正在创建复杂的状态/渲染逻辑,则最好使用 组件。针对您的特定情况的另一种选择是在顶层使用foreach 绑定(绑定到data),在选择级别使用css 绑定(绑定到selected
  • 目前我正在学习一个现实应用程序的淘汰赛。组件将是下一步。现在我对相同的数据有不同的看法,根据你的建议,我可以在它们之间同步用户选择并将所有逻辑封装在 bindingHandler 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
相关资源
最近更新 更多