允许渲染后使用注入(inject)对象的Javascript模板解决方案?

标签 javascript backbone.js handlebars.js underscore.js-templating client-side-templating

因此,我正在构建一个基于 Backbone.js 的应用程序,使用模板来渲染一些对象。

它正在工作,但是现在我需要在运行时动态引用对象,并且我不确定我所见过的模板解决方案(下划线、 Handlebars 等)是否可以“压平”javascript .

为了说明这一点,我有一个对象列表,比方说任务。 我有一个可以简化的模型:

{{#each tasks.models as |task|}}
<div>
{{task.name}}
</div>
{{/each}}

现在,我需要在渲染完成后动态使用“任务”对象。例如,执行如下操作:

<div>
{{task.name}} - <button onClick="task.setComplete()" />
</div>

当然这样不行;也不会像 {{task}}.setComplete() 那样,因为 {{task}} 在渲染时会转换为字符串。

有办法做到这一点吗?

我想我需要闭包来保留对象,获取它们的唯一方法不是压平 html,因为否则所有内容都会转换为字符串。

有什么想法吗?也许有模板库允许直接生成 DOM 对象,我可以将其添加到我的文档中?

提前致谢,

最佳答案

此问题标记为 因此您应该使用 Backbone 的普通 View 事件处理系统而不是 onclick 处理程序。您提到 tasks.models 所以大概 tasks 是一个集合。

一种方法是使用数据属性来存储模型 id。您的模板将如下所示:

{{#each tasks}}
    <div>
        {{name}} - <button data-id="{{id}}" type="button">Completed</button>
    </div>
{{/each}}

然后你的 View 将像这样设置:

Backbone.View.extend({
    events: {
        'click button': 'completed'
    },
    render: function() {
        var t = Handlebars.compile($('#whatever-the-template-is').html());
        this.$el.append(t({
            tasks: this.collection.toJSON()
        }));
        return this;
    },
    completed: function(ev) {
        var id = $(ev.currentTarget).data('id');
        var m  = this.collection.get(id);
        // Do whatever needs to be done to the model `m`...
    }   
});

演示: https://jsfiddle.net/ambiguous/z7go5ubj/

所有代码都保留在 View 中(所有数据都已存在),模板仅处理演示。没有全局变量,良好的关注点分离,以及惯用的主干结构。

如果 View 的每个模型部分更复杂,那么您可以为集合使用一个 View ,并为每个模型使用 subview 。在这种情况下,您的每个模型模板将如下所示:

<div>
    {{name}} - <button type="button">Completed</button>
</div>

不再需要数据属性。您将拥有一个新的每个模型 View ,如下所示:

var VM = Backbone.View.extend({
    events: {
        'click button': 'completed'
    },
    render: function() {
        var t = Handlebars.compile($('#whatever-the-template-is').html());
        this.$el.append(t(this.model.toJSON()));
        return this;
    },
    completed: function() {
        console.log('completed: ', this.model.toJSON());
    }   
});

循环将移动到 Collection View :

var VC = Backbone.View.extend({
    render: function() {
        this.collection.each(function(m) {
            var v = new VM({ model: m });
            this.$el.append(v.render().el);
        }, this);
        return this;
    }
});

演示: https://jsfiddle.net/ambiguous/5h5gwhep/

当然,在现实生活中,您的 VC 会跟踪其 VM,以便 VC#remove 可以调用 remove 在其所有子 VM 上。

关于允许渲染后使用注入(inject)对象的Javascript模板解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32463515/

相关文章:

javascript - 为什么将 Backbone 和 Handlebar 的上下文放入初始化函数可以消除错误?

javascript - 使用 jQuery Waypoints 在滚动条上跳转标题

javascript - Javascript 中的文字游戏

javascript - 我们如何使用 jquery 获取图像的位置并在该位置放置其他图像

Javascript/Backbone - 使用索引删除数组对象

python - 有没有一种简单的方法可以将 Flask 服务器作为可执行文件分发?

javascript - 如何在 Backbone ListView 中追加项目

javascript - Ajax 调用在 Firefox 中似乎失败

json - 使用 Handlebars.js,如何使用 JSON 文件中的值循环数据

javascript - 嵌套的 {{#each}} 不工作