我可以创建一个使用knockout.js中其他绑定的自定义绑定吗

Can I create a custom binding that uses other bindings in knockout.js

本文关键字:绑定 其他 js 自定义 knockout 创建 一个 我可以      更新时间:2023-09-26

我有一个用于翻译的自定义绑定:

ko.bindingHandlers.lang = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        this.lang = [
            'text1':'text1 translated'
            ,'text2':'text2 translated'
        ];
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var keyword = valueAccessor();
        var translatedString = this.lang[keyword];
        $(element).text(translatedString );
    }
};

我这样使用:

<span data-bind="lang:'text1'"></span>

然而,我也有一个用于创建表行格式的绑定:

ko.bindingHandlers.tableRow = {
    update : function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        $(element).html("<td>" + valueAccessor()[0] + "</td><td>" + valueAccessor()[1] + "</td>");
    }
}

我这样使用:

<tr data-bind="tableRow:['text1','text2']"></tr>

对于问题:

现在我想组合这些绑定,这样我就可以这样调用我的tableRow绑定:

<tr data-bind="tableRow:[lang:'text1','text2']"></tr>

当然,上面的代码只是举例,实际上在这些绑定中还有更多内容。

我已经阅读了多次文档,花了很长时间寻找解决方案,但什么都找不到。也许是因为无法做到这一点?

您所需要做的就是将值从一个bindingHandler传递或修改到另一个要激活的bindingHandler。

因此,在表行处理程序中,调用init和update(在它们各自的函数中):

ko.bindingHandlers.lang.init(element, valueAccessor, allBindingsAccessor, viewModel)

当然,根据需要修改参数。您可能会从数组中获取其中一个值,并将其作为第二个参数传递给init和update。

这也是激活其他标准内置绑定的好方法。

更新:添加@Joche的评论只是为了让它更可读:

var value = valueAccessor(); 
var newValueAccessor = function() {
    return translatedString; }; 
ko.bindingHandlers.lang.init(element, newValueAccessor,
       allBindingsAccessor, viewModel);

您是否可以不将转换作为一个普通函数,然后从表行绑定中调用它?

var translate = function(text)
{
        this.lang = [
            'text1':'text1 translated'
            ,'text2':'text2 translated'
        ];
    },
        var translatedString = this.lang[text];
        return translatedString;
    }
};

然后,您可以向tableRow方法传递一个额外的参数,以指示是否需要翻译:

然后,您可以在表行绑定函数中调用此函数:

ko.bindingHandlers.tableRow = {
    update : function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var text1 = valueAccessor()[2] ? translate(valueAccessor()[0]) : valueAccessor()[0];
        var text2 = valueAccessor()[2] ? translate(valueAccessor()[1]) : valueAccessor()[1];
        $(element).html("<td>" + text1 + "</td><td>" + text2 + "</td>");
    }
}

然后您可以直接从绑定元素调用它:

<span data-bind="text: translate(text1())"></span>