проблема с вложенными шаблонами - PullRequest
1 голос
/ 10 декабря 2010

Я хотел бы использовать шаблоны jQuery . На первый взгляд тег {{tmpl}} кажется правильным, но мне нужно сделать дополнительный шаг при создании шаблонов, и я не могу понять, как это сделать.

Существует определение типа данных, связанное со свойствами объекта данных. В приведенном ниже примере «фильм» представляет собой текстовое поле, «освобожден» числовое поле. Все текстовые поля используют определенный шаблон, как и все числовые поля. Эти вложенные шаблоны ничего не знают о контексте (здесь о фильмах), в котором они используются. Поэтому используемый тег всегда содержит только $ {value}. Вместо этого «внешний» шаблон знает, как должен выглядеть фильм. Его теги (фильм и выпущенный) заменяются «внутренними» шаблонами, связанными с типом данных. Дополнительным шагом является замена $ {value} до того, как будет выполнен внешний шаблон.

Все, что я мог придумать, это:

//the template used for all string-fields
var templForStrings = "<b>${value}</b>";
//the template used for all numeric fields
var templForNum = "<i>${value}</i>";

//data of a movie
var data = {};
data.movie = "Cowboys and Aliens"; //a string field
data.released = 2011; //a numeric field

//the template to show a movie
var templForMovies = "<div>{{html movie}} ({{html released}})</div>";

//normally a loop over the fields here
var field = {value: data.movie};
data.movie = $.tmpl(templForStrings, field).fullhtml();

field.value = data.released;
data.released = $.tmpl(templForNum, field).fullhtml();

//now the movie template
$.tmpl(templForMovies, data).appendTo("body");

Конечно, этот сценарий упрощен. Шаблоны типов данных намного сложнее. Данные могут быть чем угодно. Поскольку $ {value} означает две разные вещи, я не вижу, как использовать вложенные шаблоны, как это предусмотрено плагином. Но я совершенно уверен, что есть более элегантный и быстрый способ, чем мой код (для которого даже нужен fullhtml-Plugin . Было бы действительно неплохо иметь такой шаблон

<div>${movie} (${released})</div>

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

1 Ответ

1 голос
/ 21 января 2011

Возможно, вы можете использовать вспомогательную функцию для этого:

HTML:

<div id="container"></div>

<script id="tmplObject" type="text/x-jquery-tmpl">
{{each $data}}
    {{html Helper($item, $index)}}
{{/each}}
</script>

<script id="tmplNumber" type="text/x-jquery-tmpl">
number: <b>${Value}</b><br/>
</script>

<script id="tmplString" type="text/x-jquery-tmpl">
string: <i>${Value}</i><br/>
</script>

сценарий:

<script type="text/javascript">

    Helper = function($item, $index) {
        var value = $item.data[$index];
        var type = (typeof value.Value).toLowerCase();
        var tmplName = "#tmplObject";

        if (type == 'number') {
            tmplName = "#tmplNumber";
        }
        else if (type == 'string') {
            tmplName = "#tmplString";
        }

        var $node = $('<div>').append($(tmplName).tmpl(value)).remove();
        return $node.html();
    };


    $(function() {
        var data = {
            Name: { Value: "John" },
            Age: { Value: 999 },
            Type: { Value: {
                Id: { Value: 123 },
                TypeName: { Value: 'Human' }
            }
            }
        };

        $('#tmplObject').tmpl(data).appendTo('#container');
    });
</script>
...