1

我不明白以下背后的逻辑,我希望有人能帮助我理解。我正在清理一个网络应用程序,并找到了以下代码行。该应用程序是使用 Knockout.js 的 MVC 应用程序。有几个具有以下结构的自定义绑定设置:

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...
    }
};

我不明白为什么将 init & update 设置为绑定之外的变量,然后在绑定的每个部分的第一行触发?在我看来,您这样做是在创建一个循环。

任何人都可以对此有所了解吗?如果淘汰文档中包含它,我已经错过了它,为此我深表歉意。

4

1 回答 1

1

考虑一下:

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

这样,每个使用 A 的地方都有新的价值,我们仍然可以使用旧的。因为在 JavaScript 中函数是一个对象,所以你可以为它做同样的事情。保留旧的并用一些新功能覆盖它。

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

它不会创建循环,因为它不再具有相同的引用。旧引用被新函数覆盖。完美的例子在你的问题中。我们有一个knockout带有方法的库binding。为了扩展它,我们可以修改库的原始源,但是每次更新库时我们都必须这样做。我们需要的修改越多,维护就越困难。

所以我们在原来的地方写了新的绑定函数。很好,但是现在如果我们不想完全改变它而只是稍微扩展它,我们必须首先编写它所做的一切。既然已经写好了,为什么还要再写呢?我们将原始函数复制到一些新的引用:

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

然后在我们需要它完成工作时调用它:

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

我们可以将我们的扩展放在开头进行一些变量准备,然后调用原始函数来做它总是做的事情:

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

在 Knockout JS 中,还有另一种方法可以通过编写自定义绑定处理程序来做到这一点。而不是打电话给原来的。

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);
    }
};

两者都有它的缺点和优点。有时您无法修改 View 并且只能访问 ViewModel,有时您确定不需要没有扩展的原始绑定(或保留它很危险),有时您需要在几个地方修改绑定,而不是全部,然后最好创建新的绑定。

于 2013-09-04T11:05:40.883 回答