如何制作一个干净的模板并将多个项目传递给它?

时间:2013-06-13 10:16:28

标签: javascript underscore.js

我通常将下划线的模板存储在这样的数组中:

var tmpl = [
  _.template('...'),
  _.template('...'),
  _.template('...'),
]

现在我遇到的情况是我在模板中使用每个循环但想要将它移动到这个数组。静态HTML模板很简单:

var items = [
  [name: 'First'],
  [name: 'Second'],
  [name: 'Third']
];

var html = '<tr>';

_(items).each(function(item) {
  html += '<td>'+item.name+'</td>';
});

html += '</tr>';

它运行良好但很难看,所以我想把它移到 tmpl 模板列表中。所以我有这个:

var tmpl = [
  _.template('<tr><td>#{name}</td></tr>');
]

所以我的问题 - 如何在模板中构建for循环并将整个对象传递给它?

我已经重写了我的自定义模板,但它看起来实际上更糟糕而且不起作用,语法只是一团糟。这就是我所说的:

var tmpl = {
    vertical: _.template(
      '<table data-src="#{id}">'+
        '#{_(items).each(function(item) { }'+
        '<tr>'+
          '<td style="width: #{item.width}px; height: #{item.height}px">'+
            '#{item.text}'+
          '</td>'+
        '</tr>'+
        '#{ });}'+
      '</table>'
    )
  }

而不是简单明了:

var table = '<table data-src="'+id+'">';
      $(tds).each(function() {
        table += '<tr>';
          table += '<td style="width: '+$(this).width()+'px;height: '+$(this).height()+'px;">';
            table += $(this).html();
          table += '</td>';
        table += '</tr>';
      });
      table += '</table>';

请注意,我的模板语法不同。不是<%= var %>而是#{var}

_.templateSettings = { interpolate : /#\{(.+?)\}/g };

我想保留它。

1 个答案:

答案 0 :(得分:0)

以下是我使用下划线功能的方法:

var row = _.template('<td><td style="width: #{width}px; height: #{height}px">'+
                     '#{text}</td></tr>');

function rows ( items ) {
  return _.reduce( _.map( items, function( item ) { return row( item ); }),
                   function( row, memo ) { return row.concat( memo ); }, "");
}

var table = _.template('<table data-src="#{ id }">#{ rows(items) }</table>');

请注意,rows函数可以使用for循环实现,但这里的关键是它是在函数中定义的,它是您在table模板中使用的函数。然后在渲染模板时调用此函数,调用每行的模板并连接它们。

Underscore的模板引擎非常小。如果你想要更精细的东西,内置迭代器和块帮助器,我建议你看一下handlebars

无论如何,我认为这个解决方案可以使逻辑与生成的实际标记保持良好分离,从而清晰易维护。