Подтвердить что ты не робот

Могу ли я создать пользовательскую привязку, которая использует другие привязки в knockout.js

У меня есть специальная привязка для переводов:

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>

Приведенный выше код, конечно, имеет место, например, на самом деле в этих привязках больше происходит.

Я читал документацию несколько раз и долго искал решение, но ничего не мог найти. Может быть, потому что это невозможно?

4b9b3361

Ответ 1

Все, что вам нужно сделать, это передать или изменить значения из одного bindHandler другим, которые вы хотите активировать.

Итак, в обработчике tablerow вызовите init и update (в их соответствующих функциях):

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

Измените параметры, если необходимо, конечно. Вероятно, вы возьмете одно из значений из вашего массива и передадите его в качестве второго параметра для инициализации и обновления.

Это отличный способ активировать другие стандартные встроенные привязки.

Обновление: добавление комментария из @Joche, чтобы сделать его более читаемым:

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

Ответ 2

Можете ли вы не просто сделать свой перевод нормальной функцией, а затем вызвать его из привязки строки таблицы?

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>