Передача параметров шаблонам в нокауте 1.3

#javascript #knockout.js #templating #knockout-templating

#javascript #knockout.js #создание шаблонов #нокаут-создание шаблонов

Вопрос:

В knockoutjs 1.2.1 я мог бы сделать:

 <div data-bind="template: {name: 'Bar', foreach: persons, templateOptions:{fooMode: true} }"/>

<script id='Bar'>
    {{if $item.fooMode}} FOO! {{/if}}
</script>
  

Который я попытался перевести в бета-версию knockout 1.3.0 как

 <div data-bind="template: {name: 'Bar', foreach: persons, templateOptions:{fooMode: true} }"/>

<script id='Bar'>
    <span data-bind="if: $item.fooMode">FOO!</span>
</script>
  

Но новый собственный движок шаблонов не учитывает templateOptions.

Есть ли какой-либо другой способ, которым я могу передать произвольные данные в шаблон?

Ответ №1:

Как вы обнаружили, собственный движок шаблонов не поддерживает, templateOptions который был оболочкой для options функциональности подключаемого модуля шаблона jQuery.

Вы могли бы пойти двумя способами: разместить свои данные в вашей модели представления и использовать $root.fooMode or $parent.fooMode внутри вашего шаблона. Это было бы самым простым вариантом.

В противном случае, если вам не нужно значение в вашей модели представления, вы можете использовать пользовательскую привязку для управления контекстом, например:

 ko.bindingHandlers.templateWithOptions = {
    init: ko.bindingHandlers.template.init,
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, context) {
        var options = ko.utils.unwrapObservable(valueAccessor());
        //if options were passed attach them to $data
        if (options.templateOptions) {
           context.$data.$item = ko.utils.unwrapObservable(options.templateOptions);
        } 
        //call actual template binding
        ko.bindingHandlers.template.update(element, valueAccessor, allBindingsAccessor, viewModel, context);
        //clean up
        delete context.$data.$item;
    } 
}
  

Вот пример использования:http://jsfiddle.net/rniemeyer/tFJuH

Обратите внимание, что в foreach сценарии вы бы нашли свои параметры на $parent.$item , а не просто $item .

Комментарии:

1. Большое спасибо. У меня было ощущение, что bindingHandlers могли бы привести меня туда, куда я хотел, но мне потребовалось бы много времени, чтобы разобраться в этом.

2. Спасибо, это мне очень помогло. Хотя изначально это не сработало, я добился этого, изменив context.$data.$item на context.$ templateOptions вместо этого.

3. Обратите внимание, что параметры ($item) не передаются после первого применения привязок — поскольку они удалены — что делает добавление и изменение элементов непригодными для использования

Ответ №2:

Я бы предложил предложение Сандерсона, в котором вы передали бы новый литерал в данные шаблона, которые содержат модель и дополнительные данные (параметры шаблона).

 data-bind="template: { name: 'myTemplate', data: { model: $data, someOption: someValue } }"
  

Рабочая демонстрация http://jsfiddle.net/b9WWF

Источник https://github.com/knockout/knockout/issues/246#issuecomment-3775317

Комментарии:

1. Вукодже, потрясающая проницательность — спасла меня! Очень хороший, не обременительный, адаптивный подход — Спасибо!