Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RequireJS & Jquery - Multiple templates in one file?

I am loading some template files into my application using require.js like so:

define(function(require) {
    var App = require('app'),
    TeamListTmpl = require('text!templates/team-list.html'),
    PlayerListTmpl = require('text!templates/player-list.html'),
    PlayerItemTmpl = require('text!templates/player-item.html');

Then, using Backbone, I am referencing the template like so:

var PlayerItemView = Backbone.View.extend({
    tagName: "li",
    template: _.template(PlayerItemTmpl),

It's kind of annoying having individual template files and I'd like to combine all the templates into one html file and pull out individual elements. I tried this:

   define(function(require) {
        var App = require('app'),
        Templates = require('text!templates/templates-combined.html');

Where the templates-combined html file looks like this:

<div id="some-element-1">1</div>
<div id="some-element-2">2</div>
<div id="some-element-3">3</div>

But this doesn't work for some reason:

$(Templates).find("#some-element-1").html();

I also tried:

$('#some-element-1', Templates).html();

Is there any way to extract the individual template files from the one combined file without adding it to the DOM first? Perhaps using javascript templates instead? Any help would be greatly appreciated.

like image 453
Hanpan Avatar asked Jan 17 '23 07:01

Hanpan


1 Answers

I'm guessing that you want to use filter rather than find:

var some_element_1 = $(Templates).filter('#some-element-1').html();

You see, find searches within the $(Templates):

Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.

so it would find things inside those three <div>s but not the <div>s themselves; filter, on the other hand, searches through the set of elements:

Reduce the set of matched elements to those that match the selector or pass the function's test.

When you say var x = $(Templates), your x looks like this:

[
   <div id="..."></div>,
   <div id="..."></div>,
   <div id="..."></div>
]

If we look at the descendants of those <div>s (i.e. find), we won't find #some-element-1 but if we look at the set of matched elements themselves (i.e. filter) then we will find #some-element-1.

If for some reason you really want to use find, you could wrap another <div> around your templates to force them to be descendants of $(Template):

<div>
    <div id="some-element-1">1</div>
    <div id="some-element-2">2</div>
    <div id="some-element-3">3</div>
</div>

I'd also recommend that you wrap your templates in <script> elements rather than <div>s:

<script type="text/x-template" id="some-element-1">1</script>
<script type="text/x-template" id="some-element-2">2</script>
<script type="text/x-template" id="some-element-3">3</script>

The browser will treat <script>s as opaque black boxes (provided you use the right type attribute) but it might try to interpret and correct the contents of <div>s. The problem is that your templates might not be valid HTML until after you've processed them and filled them in; if you let a browser get its hands on invalid HTML it might try to correct it and that can make a big mess of your templates.

like image 107
mu is too short Avatar answered Jan 28 '23 05:01

mu is too short