4

我正在使用 require.js 将一些模板文件加载到我的应用程序中,如下所示:

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');

然后,使用 Backbone,我像这样引用模板:

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

拥有单独的模板文件有点烦人,我想将所有模板合并到一个 html 文件中并提取单独的元素。我试过这个:

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

模板组合的 html 文件如下所示:

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

但这由于某种原因不起作用:

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

我也试过:

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

有什么方法可以从一个组合文件中提取单个模板文件而不先将其添加到 DOM 中?也许改用javascript模板?任何帮助将不胜感激。

4

1 回答 1

9

我猜你想使用filter而不是find

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

你看,find$(Templates):

获取当前匹配元素集中每个元素的后代,由选择器、jQuery 对象或元素过滤。

所以它会在这三个 s 中找到东西,<div>而不是<div>s 本身;filter,另一方面,搜索元素集:

将匹配元素集减少为匹配选择器或通过函数测试的元素。

当你说 时var x = $(Templates),你的x样子是这样的:

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

如果我们查看那些s 的后代<div>(即find),我们不会找到#some-element-1,但如果我们查看匹配元素本身的集合(即filter),那么我们会找到#some-element-1

如果出于某种原因您真的想使用find,您可以在您的模板周围包装另一个<div>以强制它们成为以下内容的后代$(Template)

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

我还建议您将模板包装在<script>元素中,而不是<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>

浏览器会将<script>s 视为不透明的黑盒子(前提是您使用了正确的type属性),但它可能会尝试解释和更正<div>s 的内容。问题是您的模板可能不是有效的 HTML,直到您处理并填写它们之后;如果您让浏览器处理无效的 HTML,它可能会尝试更正它,这可能会使您的模板变得一团糟。

于 2012-06-24T16:29:49.110 回答