怎么做"点击:test()"在KO工作?

时间:2017-05-24 08:28:10

标签: javascript knockout.js

我的观点模型

function Test() {}
Test.prototype.test = function() { alert('hi'); }

我的观点

<button data-bind="click: test()">Click me</button>

运行它的代码

var test = new Test();
ko.applyBindings(test);

小提琴:    https://jsfiddle.net/5g4cfg7u/

问题:

  • 任何人都可以解释这里发生了什么,test()是一个调用表达式,它应该在绑定时被评估为undefined(你可以在显示警报时看到它)第一次),所以click: test()click: undefined一样好,如果是这样的话,当我点击按钮时,我怎么看警报?

  • 任何人都可以共享指向解释它的官方Knockout文档的链接吗?

更新

为了更好地说明,如果我们添加另一个绑定text: test(),我们会看到按钮上的文本在绑定时消失(正如预期的那样,因为测试返回undefined),如果是这样,评估{{}之间有什么区别? 1}}和click

text

https://jsfiddle.net/5g4cfg7u/3/

更新

在淘汰赛中转发:https://github.com/knockout/knockout/issues/2246

3 个答案:

答案 0 :(得分:3)

在内部,绑定click: test()会转换为click: function() { return test() }。然后将“value-accessor”函数传递给绑定处理程序。检查event绑定的codeclick使用),我们可以看到每次事件发生时都会调用valueAccessor。然后绑定使用值访问器的结果。

这就是为什么你不应该使用click: test()

  1. 首次应用绑定时,该函数将被称为initially。你可能永远不会想那样。
  2. 如果正确设置绑定,默认的click行为不会被取消。请参阅https://jsfiddle.net/5g4cfg7u/6/
  3. 更多信息:

    Knockout documentation中所述,绑定可以包含JavaScript表达式,例如text: price() > 50 ? 'expensive' : 'cheap'。任何绑定都是如此。每当更新绑定时,将重新评估表达式。对于事件,最初评估表达式,然后在事件发生时评估。 event绑定期望表达式返回一个函数,但它silently ignores a falsy return value(例如undefined)。

    如果您确实要将事件绑定到要运行的表达式,请查看on.* bindings中的http://mbest.github.io/knockout.punches/

答案 1 :(得分:1)

“click”绑定接受将在点击时调用的函数。

data-bind="click: test()"

计算“click()”函数并将返回的结果传递给click绑定处理程序。

var model = {
  testFunc: function(model) {
    alert(model.text())
  },
  text: ko.observable("some text")
}

ko.applyBindings(model);

setTimeout(function() { model.text("another text"); }, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<button data-bind="click: testFunc, text: text">
Click me
</button>

The "click" binding documentation

更新1。

我很抱歉在这里引用文档,但它清楚地说明了

  

主要参数

     

要绑定到元素单击事件的函数。

并且无关紧要 - 如何获得此函数:从内联字符串求值,通过引用传递或作为内联求值函数或其他函数或可观察对象的值返回返回。

更新2。

KnockoutJS包装你的表达式以便对其进行评估,或者在它的值是可观察的情况下重新评估。这就是为什么你的函数在点击时被调用,尽管没有返回任何东西。在评估绑定表达式之后,它将转换为此代码:

(function($context,$element
/*``*/) {
with($context){with($data||{}){return{'click':function(){return test() }}}}
})

如果添加“调试器”作为“测试”功能的第一行,您可以检查它。我没有在KnockoutJS文档中找到这个。这有点令人困惑,但很容易调试。

答案 2 :(得分:0)

调用click: test可以正常工作,因为它需要调用一个函数(一旦绑定到您的viewmodel,就会尽职尽责地显示警报)。

调用text: test()会返回undefined,因为该功能没有返回值。