gpt4 book ai didi

javascript - Knockout - 单击绑定(bind)行为

转载 作者:行者123 更新时间:2023-12-02 13:50:09 27 4
gpt4 key购买 nike

我的问题是关于 Knockout 中的点击绑定(bind),以及为什么会发生以下行为。我在这里发现了许多点击绑定(bind)问题,但并非特定于我在下面描述的行为。

据我了解,在 Knockout 中,带有参数的单击绑定(bind)是在页面加载时执行的,因为 Knockout 需要一个引用(对函数),因此当它在绑定(bind)中遇到函数调用时,它将执行该函数,并期望返回的函数引用来绑定(bind)到。因此,如果我返回对函数的另一个引用,则该函数将在元素单击时执行。

到目前为止一切顺利,这是有道理的。

为了亲眼目睹这一点,我很快创建了这个:

HTML:

<input data-bind="click: selectImportType(1)" type="button" />

JS

var functiontest = function () {
alert('test');
};

viewModel.selectImportType = function (type) {
viewModel.selectedImport(type);

return functiontest;
}

执行此操作后,我发现“functiontest”引用返回到绑定(bind),因为单击按预期调用了 functiontest 函数。

现在让我感到困惑。我发现当单击元素时也会调用 selectImportType 函数。首先调用 selectImportType,然后调用 functiontest 函数。

这怎么可能?绑定(bind)期间解析的引用是对功能测试函数的引用!

最佳答案

当你写的时候

data-bind="click: selectImportType(1)"

表达式 selectImportType(1) 被评估并返回您的 functiontest 函数,然后将其分配给点击绑定(bind)。

为什么?

因为这是设计使然。

当 knockout 解析绑定(bind)时,它会创建绑定(bind)字符串计算器,它只是动态函数:

function createBindingsStringEvaluator(bindingsString, options) {
// Build the source for a function that evaluates "expression"
// For each scope variable, add an extra level of "with" nesting
// Example result: with(sc1) { with(sc0) { return (expression) } }
var rewrittenBindings = ko.expressionRewriting.preProcessBindings(bindingsString, options),
functionBody = "with($context){with($data||{}){return{" + rewrittenBindings + "}}}";
return new Function("$context", "$element", functionBody);
}

在您的情况下,functionBody 是:

"with($context){with($data||{}){return{'click':function(){return selectImportType(1) }}}}"

它被评估以获得像这样的 parsedBindings ( https://github.com/knockout/knockout/blob/v3.4.1/src/binding/bindingProvider.js#L27 )

{
"click": function(){return selectImportType(1)}
}

将通过以下方式传递给bindginHandler:

var valueAccessor = getValueAccessor(bindingKey);
||
click

所以 valueAccessor 是函数:

function(){return selectImportType(1)}

然后我们看一下事件绑定(bind)的源码( https://github.com/knockout/knockout/blob/v3.4.1/src/binding/defaultBindings/event.js#L6-L18 ):

ko.bindingHandlers[eventName] = {
'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var newValueAccessor = function () {
var result = {};
result[eventName] = valueAccessor(); // 1
return result;
};
return ko.bindingHandlers['event']['init'].call(this, element, newValueAccessor, allBindings, viewModel, bindingContext);
}
}

ko.bindingHandlers['event'] = {
'init' : function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var eventsToHandle = valueAccessor() || {}; // 2

如您所见,valueAccessor 被包装在 newValueAccessor 中,并且当 knockout 获取点击事件的处理程序时(请参阅注释 2)newValueAccessor 是也进行了评估,您将获得执行结果 selectImportType(1)

最后,eventsToHandle 将是您的functiontest:

function () {
alert('test');
}

这就是为什么单击按钮时会调用 functiontest 函数

<小时/>

我猜你正在寻找类似的东西:

data-bind="click: selectImportType.bind($data, 1)"

在这种情况下,仅在单击按钮元素后才会调用 selectImportType 函数。

关于如何在 knockout 绑定(bind)中将参数传递给函数存在很多问题

关于javascript - Knockout - 单击绑定(bind)行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41065597/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com