Внешний шаблон в подчеркивании
я использую подчеркивания шаблон. Можно прикрепить внешний файл как шаблон?
в представлении позвоночника у меня есть:
textTemplate: _.template( $('#practice-text-template').html() ),
initialize: function(){
this.words = new WordList;
this.index = 0;
this.render();
},
в моем html это:
<script id="practice-text-template" type="text/template">
<h3>something code</h3>
</script>
Он работает хорошо. Но мне нужен внешний шаблон. Я стараюсь:
<script id="practice-text-template" type="text/template" src="templates/tmp.js">
или
textTemplate: _.template( $('#practice-text-template').load('templates/tmp.js') ),
или
$('#practice-text-template').load('templates/tmp.js', function(data){ this.textTemplate = _.template( data ) })
но это не сработало.
12 ответов:
EDIT: этот ответ старый и устаревший. Я бы удалил его, но это" принятый " ответ. Вместо этого я введу свое мнение.
Я бы не стал больше этого делать. Вместо этого я бы разделил все шаблоны на отдельные HTML-файлы. Некоторые из них предлагают загружать их асинхронно (требуется.js или шаблон кэша видов). Это хорошо работает на небольших проектах, но на больших проектах с большим количеством шаблонов вы обнаружите, что делаете тонну маленькой асинхронности запросы на загрузку страницы, которые мне действительно не нравятся. (тьфу... хорошо, вы можете обойти это с Require.js путем предварительной компиляции ваших начальных зависимостей с помощью r. js, но для шаблонов это все еще кажется мне неправильным)
мне нравится использовать задачу grunt (grunt-contrib-jst) для компиляции всех шаблонов HTML в один шаблон.JS-файл и включите его. Вы получаете лучшее из всех миров ИМО... шаблоны живут в файле, компиляция указанных шаблонов происходит во время сборки (не во время выполнения), и у вас нет сотни крошечных асинхронных запросов, когда страница запускается.
все, что ниже-хлам
для меня я предпочитаю простоту включения JS-файла с моим шаблоном. Итак, я мог бы создать файл с именем view_template.js, который включает шаблон в качестве переменной:
app.templates.view = " \ <h3>something code</h3> \ ";
тогда это так же просто, как включить файл сценария, как обычный, а затем использовать его в своем представлении:
template: _.template(app.templates.view)
Сделай шаг далее, я на самом деле используйте coffeescript, так что мой код на самом деле выглядит более так и избежать конца строки escape-символов:
app.templates.view = ''' <h3>something code</h3> '''
использование этого подхода позволяет избежать засолки в require.js, где это действительно не нужно.
вот простое решение:
var rendered_html = render('mytemplate', {}); function render(tmpl_name, tmpl_data) { if ( !render.tmpl_cache ) { render.tmpl_cache = {}; } if ( ! render.tmpl_cache[tmpl_name] ) { var tmpl_dir = '/static/templates'; var tmpl_url = tmpl_dir + '/' + tmpl_name + '.html'; var tmpl_string; $.ajax({ url: tmpl_url, method: 'GET', dataType: 'html', //** Must add async: false, success: function(data) { tmpl_string = data; } }); render.tmpl_cache[tmpl_name] = _.template(tmpl_string); } return render.tmpl_cache[tmpl_name](tmpl_data); }
использование "async: false" здесь не плохой способ, потому что в любом случае вы должны ждать, пока шаблон будет загружен.
Итак, функция "render"
- позволяет хранить каждый шаблон в отдельном html-файле в статическом режиме реж
- очень легкий
- компилирует и кэширует шаблоны
- абстрактная логика загрузки шаблона. Например, в будущем вы можете использовать предустановленные и предварительно скомпилированные шаблоны.
- прост в использовании
[я редактирую ответ вместо того, чтобы оставить комментарий, потому что я считаю, что это важно.]
Если шаблоны не отображаются в приложение, а вы видите
HIERARCHY_REQUEST_ERROR: DOM Exception 3
, посмотрите на ответ Дэйва Робинсона на что именно может вызвать"HIERARCHY_REQUEST_ERR: DOM Exception 3" -ошибка?.в принципе, вы должны добавить
dataType: 'html'
к $.запрос AJAX.
этот mixin позволяет отображать внешний шаблон с помощью подчеркивание очень просто:
_.templateFromUrl(url, [data], [settings])
. Метод API почти такой же, как библиотеки Underscore!--5-->_.template (). Кэширование включено._.mixin({templateFromUrl: function (url, data, settings) { var templateHtml = ""; this.cache = this.cache || {}; if (this.cache[url]) { templateHtml = this.cache[url]; } else { $.ajax({ url: url, method: "GET", async: false, success: function(data) { templateHtml = data; } }); this.cache[url] = templateHtml; } return _.template(templateHtml, data, settings); }});
использование:
var someHtml = _.templateFromUrl("http://example.com/template.html", {"var": "value"});
Я не хотел использовать require.js для этой простой задачи, поэтому я использовал модифицированное решение коорчика.
function require_template(templateName, cb) { var template = $('#template_' + templateName); if (template.length === 0) { var tmpl_dir = './templates'; var tmpl_url = tmpl_dir + '/' + templateName + '.tmpl'; var tmpl_string = ''; $.ajax({ url: tmpl_url, method: 'GET', contentType: 'text', complete: function (data, text) { tmpl_string = data.responseText; $('head').append('<script id="template_' + templateName + '" type="text/template">' + tmpl_string + '<\/script>'); if (typeof cb === 'function') cb('tmpl_added'); } }); } else { callback('tmpl_already_exists'); } } require_template('a', function(resp) { if (resp == 'tmpl_added' || 'tmpl_already_exists') { // init your template 'a' rendering } }); require_template('b', function(resp) { if (resp == 'tmpl_added' || 'tmpl_already_exists') { // init your template 'b' rendering } });
зачем добавлять шаблоны в документ, а не хранить их в объекте javascript? Потому что в производственной версии я хотел бы создать html-файл со всеми уже включенными шаблонами, поэтому мне не нужно будет делать никаких дополнительных запросов ajax. И в то же время мне не нужно будет делать рефакторинг в моем коде, так как я использую
this.template = _.template($('#template_name').html());
в моем позвоночнике просмотр.
это может быть немного не по теме, но вы можете использовать Grunt (http://gruntjs.com/) - который работает на узле.js (http://nodejs.org/, доступно для всех основных платформ) для выполнения задач из командной строки. Есть куча плагинов для этого инструмента, как компилятор шаблонов,https://npmjs.org/package/grunt-contrib-jst. смотрите документацию на GitHub,https://github.com/gruntjs/grunt-contrib-jst. (Вам также нужно будет понять, как запустить Диспетчер пакетов узлов, https://npmjs.org/. Не волнуйтесь, это невероятно легко и универсально. )
затем вы можете сохранить все свои шаблоны в отдельных html-файлах, запустить инструмент для предварительной компиляции их всех с помощью подчеркивания (что я считаю зависимостью для плагина JST, но не волнуйтесь, менеджер пакетов узлов автоматически установит зависимости для вас).
это компилирует все ваши шаблоны в один скрипт, скажем
templates.js
загрузка скрипта установит глобальный - " JST " по default-который представляет собой массив функций, и может быть доступен следующим образом:
JST['templates/listView.html']()
который был бы похож на
_.template( $('#selector-to-your-script-template'))
если вы поместите содержимое этого тега сценария в (templates/)listView.HTML-код
однако настоящий Кикер заключается в следующем: Grunt поставляется с этой задачей под названием "watch", которая в основном будет отслеживать изменения файлов, которые вы определили в своем локальном grunt.JS-файл (который в основном является конфигурационным файлом для вашего проекта Grunt, в яваскрипт.) Если у вас есть grunt начать эту задачу для вас, набрав:
grunt watch
из командной строки Grunt будет отслеживать все изменения, внесенные в файлы, и автоматически выполнять все задачи, которые вы настроили для него в этом grunt.JS файл, если он обнаруживает изменения - как jst задач, описанных выше. Отредактируйте и сохраните файлы, и все ваши шаблоны перекомпилируются в один js-файл, даже если они распределены по нескольким каталогам и подкаталогам.
подобных задач можно настроить для автоматической проверки кода ваш JavaScript, запуск тестов, объединение и сокращение / уродуя свои файлы скриптов. И все они могут быть привязаны к задаче watch, поэтому изменения в ваших файлах автоматически вызовут новую "сборку" вашего проекта.
требуется некоторое время, чтобы настроить вещи и понять, как настроить ворчание.JS файл, но это хорошо, хорошо стоит потраченного времени, и я не думаю, что вы когда-нибудь вернетесь к пре-ворчливому способу работает
Я думаю этой - это то, что может помочь вам. Все в решении вращается вокруг
require.js
библиотека, которая является загрузчиком файлов и модулей JavaScript.учебник по ссылке выше очень хорошо показывает, как можно организовать базовый проект. А пример реализации также предоставляется. Надеюсь, это поможет.
Я заинтересовался шаблоном javascript, и теперь я делаю первые шаги с backbone. Это то, что я придумал и, кажется, работает довольно хорошо.
window.App = { get : function(url) { var data = "<h1> failed to load url : " + url + "</h1>"; $.ajax({ async: false, url: url, success: function(response) { data = response; } }); return data; } } App.ChromeView = Backbone.View.extend({ template: _.template( App.get("tpl/chrome.html") ), render: function () { $(this.el).html(this.template()); return this; }, }); App.chromeView = new App.ChromeView({ el : document.body }); App.chromeView.render();
Я должен был задать тип данных "текст", чтобы заставить его работать для меня:
get : function(url) { var data = "<h1> failed to load url : " + url + "</h1>"; $.ajax({ async: false, dataType: "text", url: url, success: function(response) { data = response; } }); return data; }
Я нашел решение, которое работает для меня с помощью jQuery.
я добавляю код шаблона подчеркивания с помощью jQuery.метод load (), в основной HTML-файл.
как только он там, я использую его для создания шаблонов. Все должно происходить синхронно!
концепция:
у меня есть код шаблона карты подчеркивания:
<!-- MAP TEMPLATE--> <script type="text/template" id="game-map-template"> <% _.each(rc, function(rowItem, index){ %> <ul class="map-row" data-row="<%- index %>"> <li class="map-col <%- colItem.areaType ? 'active-area' : '' %>"></li> ... </script>
и я положил этот код в файл под названием карта-шаблон.HTML-код
после этого я создаю оболочку для файлов шаблона.
<div id="templatesPool"></div>
затем я включаю этот файл в свой основной html-файл вот так.
в голову:
<!-- Template Loader --> <script> $(function(){ $("#templatesPool").append($('<div>').load("map-template.html")); }); </script>
ваше здоровье.
Я знаю, что этот вопрос действительно старый, но он появился как первый результат поиска google для шаблонов подчеркивания ajax.
Я устал не найти хорошее решение для этого, поэтому я создал свой собственный:
https://github.com/ziad-saab/underscore-async-templates
в дополнение к загрузке шаблонов подчеркивания с помощью AJAX, он добавляет функциональность. Я надеюсь, что это может быть полезно кому-то.
мне было немного непросто заставить jQuery работать синхронно, поэтому я изменил предыдущий синхронный пример, используя обещания. Это почти то же самое, но работает асинхронно. Я использую шаблоны hbs в этом примере:
var asyncRenderHbs= function(template_name, template_data) { if (!asyncRenderHbs.template_cache) { asyncRenderHbs.template_cache= {}; } var promise= undefined; if (!asyncRenderHbs.template_cache[template_name]) { promise= new Promise(function(resolve, reject) { var template_url= '/templates/' + template_name; $.ajax({ url: template_url, method: 'GET', success: function(data) { asyncRenderHbs.template_cache[template_name]= Handlebars.compile(data); resolve(asyncRenderHbs.template_cache[template_name](template_data)); }, error: function(err, message) { reject(err); } }); }); } else { promise= Promise.resolve(asyncRenderHbs.template_cache[template_name](template_data)); } return promise; };
затем использовать визуализированный html:
asyncRenderHbs('some_template.hbs', context) .then(function(html) { applicationMain.append(html); // Do other stuff here after html is rendered... }) .catch(function(err) { // Handle errors });
Примечание: как обсуждалось другими, было бы предпочтительно скомпилировать все шаблоны в один шаблон.JS-файл и загрузить его в начале, а не иметь много небольших синхронных AJAX вызовы для получения шаблонов при загрузке веб-страницы.
вперед внимание-здесь будут драконы:
я упоминаю подход, показанный ниже, просто чтобы помочь тем, кто изо всех сил пытается сделать ASP.NET стеки (и подобные структуры) работают гармонично с экосистемой JS-libs. Само собой разумеется, что это не общее решение. Сказав это ...
/endforwardwarning
Если вы используете ASP.NET вы можете экстернализировать свои шаблоны, просто поместив их в одно или несколько собственных частичных представлений. Также известный как внутри тебя .cshtml:
@Html.Partial("path/to/template")
внутри шаблона.cshtml:
// this is razorview and thusly if you ever need to use the @ character in here // you will have to either escape it as @@ or use the html codepoint which is @ // http://stackoverflow.com/questions/3626250/escape-character-in-razor-view-engine <script type="text/x-template" id="someId"> <span class="foo"><%= name %></span> </script>
и теперь вы можете использовать шаблон, как обычно:
_.template($("#someId").html())({ name: "Foobar" });
надеюсь, что этот неуловимо-очевидный подход поможет кому-то сэкономить час на почесывание головы.