简体   繁体   English

Knockout.js自定义绑定设计

[英]Knockout.js custom binding design

I do not understand the logic behind the following and I am hoping someone can help me understand. 我不了解以下内容的逻辑,希望有人能帮助我理解。 I am cleaning up a web app and have found the following lines of code. 我正在清理一个Web应用程序,发现以下代码行。 The app is an MVC app using Knockout.js. 该应用程序是使用Knockout.js的MVC应用程序。 There are several custom bindings setup with the following structure: 有几种具有以下结构的自定义绑定设置:

var originalBindingInit = ko.bindingHandlers.binding.init;
var originalBindingUpdate = ko.bindingHandlers.binding.update;

ko.bindingHandlers.binding = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        originalBindingInit(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);

        // Init code here... 
    },

    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        originalBindingUpdate(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);

        // Update code here...
    }
};

I do not understand why the init & update are being set to variables outside of the binding and then fired on the first line of each section of the binding? 我不明白为什么将init&update设置为绑定之外的变量,然后在绑定的每个部分的第一行上触发? It would seem to me that you are creating a loop by doing this. 在我看来,您正在通过此操作创建一个循环。

Can anyone shed some light on this? 谁能对此有所启发? If it's covered in the knockout documentation, I have missed it and for that I do apologize. 如果击倒文档中涵盖了该内容,则我会错过它,为此我深表歉意。

Consider this: 考虑一下:

var A = 1;
var originalA = A;
A = 2;

This way every place where A was used has new value and we can still use the old one. 这样,每个使用A的地方都有新的价值,我们仍然可以使用旧的价值。 Since in JavaScript function is an object you can do the same for it. 由于JavaScript函数中的对象是对象,因此可以对其执行相同的操作。 Keep the old one and overwrite it with some new functionality. 保留旧版本并用一些新功能覆盖它。

var functionA = function () {};
var originalFunctionA = functionA;
functionA = function () {};

It doesn't create the loop because it no longer has the same reference. 它不会创建循环,因为它不再具有相同的引用。 Old reference is overwritten by new function. 旧参考被新功能覆盖。 Perfect example is in your question. 完美的例子在您的问题中。 We've got a library knockout with a method binding . 我们有一个带有方法binding的库knockout To extend it we can modify original source of the library but then we will have to do it each time library is updated. 为了扩展它,我们可以修改库的原始源,但是每次更新库时都必须这样做。 The more such modifications we need the harder maintaining will be. 我们需要的此类修改越多,维护就越困难。

So we write the new binding function at the place of original one. 因此,我们在原始绑定函数的位置编写了新的绑定函数。 Nice, but now if we don't want to change it completely and just extend it a little bit we have to write everything it done in the first place. 很好,但是现在,如果我们不想完全更改它,而只是稍微扩展一下,我们必须首先编写它所做的所有事情。 Why write it again when it was already written? 为什么已经写了再写一次? We copy the original function to some new reference: 我们将原始函数复制到一些新参考中:

var originalBindingInit = ko.bindingHandlers.binding.init;
var originalBindingUpdate = ko.bindingHandlers.binding.update;

and then call it when we need it to do its job: 然后在需要它进行工作时调用它:

var bindingInit = function () {
    // do sth befeore
    originalBindingInit( someVariable );
    // do sth after
}

We can put our extension at the beginning for some variable preparations and then call original function to do what it always does: 我们可以将扩展名放在开头,以进行一些变量准备,然后调用原始函数来执行其始终执行的操作:

var someRoundedVariable = Math.round( someVariable );
originalBindingInit( someRoundedVariable );

In Knockout JS there is another way to do this by writing custom binding handler. 在Knockout JS中,还有另一种方法可以通过编写自定义绑定处理程序来实现。 And than call the original one. 并且比起原始的。

ko.bindingHandlers.verifyValue = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // do sth to verify value and than call other binding:
        ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // The rest of this binding is handled by the default value binding. Pass it on!
        ko.bindingHandlers.value.update(element, newValueAccessor, allBindingsAccessor, viewModel, bindingContext);
    }
};

Both have it cons and pros. 两者都有其优点和缺点。 Sometimes you can't modify View and have access to just ViewModel, sometimes you are sure you don't need the original binding without extensions (or keeping it is dangerous) other time you need modified binding in few places not all of them and then it's better to create new binding. 有时您无法修改View并只能访问ViewModel,有时您确定不需要扩展而无需原始绑定(否则很危险),而其他时候则需要在几个地方(而不是全部)修改绑定最好创建新的绑定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM