在 ko 绑定中包含括号会影响评估顺序吗?为啥?

Posted

技术标签:

【中文标题】在 ko 绑定中包含括号会影响评估顺序吗?为啥?【英文标题】:Does including parenthesis in ko binding affect order of evaluation? Why?在 ko 绑定中包含括号会影响评估顺序吗?为什么? 【发布时间】:2015-06-30 08:16:25 【问题描述】:

我使用 KO 和一些非常简单的代码,但我看到了一些奇怪的东西。

<div class="upload-progress" data-bind="visible: isUploading">
  <div class="upload-progress-spinner" data-bind="spinner: isUploading" />
</div>

这会使微调器(第二个 div)看起来有点不合适,但是如果我在第二个 ko 绑定中添加括号,如下所示:

<div class="upload-progress" data-bind="visible: isUploading">
  <div class="upload-progress-spinner" data-bind="spinner: isUploading()" />
</div>

...现在位置正确。为什么在我的 ko 绑定中添加括号会产生这样的效果?我的猜测是它以某种方式改变了评估的顺序,但我不确定为什么。有人对此有任何见解吗?

注意:“spinner”是一个自定义的 KO 绑定,但我认为它的逻辑不会导致这种定位怪癖。

编辑:这里是微调器自定义绑定,以防相关:

  ko.bindingHandlers.spinner = 
update: function (element, valueAccessor) 
  var bindingValue = valueAccessor().show || valueAccessor();
  var defaults =  lines: 8, length: 2, width: 2, radius: 3, speed: 1.3, trail: 60, shadow: false ;
  var options = valueAccessor().options || ;
  $.extend(options, defaults);

  if (bindingValue)
    setTimeout(function ()  $(element).spin(options); , 1);
  else
    $(element).spin(false);

;

【问题讨论】:

var foo = bar() 立即执行 bar 函数并将其返回值分配给 foo。 var foo = bar 会将 bar 的值分配给 foo。如果 bar 是一个函数,那么 foo 本质上就变成了一个指向该函数的指针,然后你可以 foo() 并且条形码会执行。 spinner: isUploading 允许敲除观察 observable 并在绑定发生变化时对其进行修改。 spinner: isUploading() 将评估 observable 并将值传递给 spinner 在呈现元素时绑定,并且不会传递更改。为什么这会改变您所看到的取决于 spinner 绑定的预期以及它对所给内容的作用,因此是评论而不是答案。 @JamesThorpe 感谢您的回答。我已经包含了我的微调器绑定的代码,它并没有做任何非常有趣的事情。 @FreakinOutMan 您是否在浏览器控制台中遇到任何错误/在运行第二个版本时微调器是否按预期运行?看起来它希望将一个可观察对象传递给它(它正在调用valueAccessor(),所以如果isUploading 是一个布尔可观察对象(我假设它是基于它的名称以及您在visible 上使用它的事实) ),我希望将 isUploading() 传递给它(这反过来会在绑定中有效地调用 true()false())会导致一些问题 @JamesThorpe 我没有收到任何错误,并且微调器在任一版本中都能正常工作。第一个 sn-p 中的位置不正确,但在第二个 sn-p 中位置正确。我猜 KO 足够聪明,可以弄清楚我给绑定的内容是可观察的,无论我是否包含括号? 【参考方案1】:

我怀疑您没有正确读取配置的选项,因为您没有正确地“解包”绑定处理程序中的 observable。

所以你真的用不同的选项调用微调器,这取决于你是否提供括号......这是真正的问题。

您应该这样做(注意这是淘汰赛 3 语法,如果您使用淘汰赛 2.x,请使用 ko.unwrapObservable)

ko.bindingHandlers.spinner = 
    update: function (element, valueAccessor) 
        var value = valueAccessor();
        var valueUnwrapped = ko.unwrap(value);
        var bindingValue = valueUnwrapped.show || valueUnwrapped;
        var defaults =  lines: 8, length: 2, width: 2, radius: 3, speed: 1.3, trail: 60, shadow: false ;
        var options = valueUnwrapped.options || ; // this is the key line
        $.extend(options, defaults);

       if (bindingValue)
           setTimeout(function ()  $(element).spin(options); , 1);
       else
           $(element).spin(false);
       
   

来自文档:

valueAccessor — 一个 javascript 函数,您可以调用它来获取 此绑定中涉及的当前模型属性。调用这个 不传递任何参数(即调用 valueAccessor())来获取 当前模型属性值。轻松接受可观察的和 纯值,在返回值上调用 ko.unwrap

【讨论】:

我所做的假设(“我的自定义绑定很好”)结果证明是问题所在。正确解开值可以解决问题!谢谢!

以上是关于在 ko 绑定中包含括号会影响评估顺序吗?为啥?的主要内容,如果未能解决你的问题,请参考以下文章

() 优先级最高,为啥会短路?

为啥我的 ko 计算 observable 在其值更改时不会更新绑定的 UI 元素?

为啥迭代二维数组时循环的顺序会影响性能?

为啥括号会影响 TypeScript 中的类型缩小?

为啥具有短路操作的并行 Java Stream 会评估 Stream 的所有元素,而顺序 Stream 不会?

这两个postgres表达式会给出相同的结果吗?