2014-12-01 2 views
0

Я пытаюсь создать компонент таблицы в нокауте, который может отображать произвольные столбцы таким образом, который по-прежнему использует нокаут для содержимого ячеек. Я передаю массив объектов определения столбцов в компонент и массив произвольных объектов строки. Тогда, у меня есть вложенная структура Еогеаспа, которая выглядит немного как это:Динамическая обработка шаблона с помощью Knockout.js

<tbody data-bind="foreach: {data:rows, as:'row'}"> 
    <tr data-bind="foreach: $parent.columns"> 
    <td data-bind="html:renderCell(row)"></td> 
    </tr> 
</tbody> 

С этим я могу позволить функцию «renderCell» для каждого столбца, чтобы вернуть некоторый HTML идти в клетке, учитывая контекст строка viewModel.

Однако, что я действительно хочу, чтобы иметь возможность вернуть шаблон нокаута для ячейки. Я не хочу использовать шаблоны стиля <script type="text/html" id="xyz">, потому что он не подходит для этого конкретного приложения, но я не могу понять, как получить нокаут для обработки вывода из renderCell() в виде строки шаблона.

Как я могу сделать что-то вроде следующего и заставить его работать?

<td data-bind="template:{fn: renderCell(row)}"></td> 

Я хотел бы использовать другие компоненты, такие как и другие привязки, на выходе функции renderCell.

ответ

1

Так как я понимаю, вам нужен пользовательский шаблон для каждой ячейки. Этот шаблон должен основываться на информации, поступающей в привязку. Шкаф, что я могу думать, чтобы позволить вам сделать это пользовательские привязки обработчика:

ko.bindingHandlers.yourBindingName = { 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     // This will be called when the binding is first applied to an element 
     // Set up any initial state, event handlers, etc. here 
    }, 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     // This will be called once when the binding is first applied to an element, 
     // and again whenever any observables/computeds that are accessed change 
     // Update the DOM element based on the supplied values here. 
    } 
}; 

Так что это основная один из документации нокаута. Я предполагаю, что в функции инициализации, то вы можете выбрать некоторый HTML, который вы хотите для отображения:

function customTemplateOne(dataToBind) { 
    var spanEl = document.createElement('span'); 
    spanEl.innerHTML = dataToBind; 
    return spanEl; 
} 

Вы можете иметь целый набор различных функций для определения различных шаблонов.

В вашей инициализации вы можете сделать это:

var template = ""; 
switch (valueToDetermineTemplateChange) 
{ 
    case "useThis": 
     template = customTemplateOne(dataToBind); 
} 

Или вы можете воспользоваться JavaScripts значение ключа вещи.

var templates = { 
    useThis: function() {} 
} 

var template = templates[valueToDetermineTemplateChange](); 

Для того, чтобы сделать пользовательские параметры вы можете сделать это:

ko.bindingHandlers.yourBindingName = { 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     // This will be called when the binding is first applied to an element 
     // Set up any initial state, event handlers, etc. here 

     var options = {}; 

     ko.extend(options, ko.bindingHandlers.yourBindingName); // get the global options 
     ko.extend(options, ko.unwrap(valueAccessor())); // merge with the local options 

     // so if you have a data property on the options which holds the ko binding you can do this: 
     var data = ko.unwrap(options.data); 
    }, 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     // This will be called once when the binding is first applied to an element, 
     // and again whenever any observables/computeds that are accessed change 
     // Update the DOM element based on the supplied values here. 
    }, 
    options: { 
     customOption: "Some Option" 
    } 
}; 

<div data-bind="yourBindingName: { data: someValue }"></div> 

Вместо функции applyBindingsToDescendants, вы сделаете свою инициализацию обхват других привязок:

ko.applyBindingsToNode(element, { html: valueAccessor() }, context); // the html is a binding handler, you can specify with, text, foreach.... 
+0

Но это будет работать только с шаблонами в форме . Я пытаюсь использовать функцию для возврата текста шаблона вместо тега скрипта. –

+0

Я обновил ответ –

+0

Спасибо, но опять же, это просто возвращает «имя» тега скрипта, в котором есть шаблон html, а не сам текст шаблона –

Смежные вопросы