Backbone.js 视图实例变量?

13

我正在学习Backbone.js,想知道在Backbone视图中是否可以有实例变量。

我的目标是在实例化视图时从外部文件加载视图的模板。目前,我将它们存储在Backbone应用程序全局命名空间的全局变量中,但将模板存储在视图的实例变量中会更清晰。目前,我设置如下:

var templates = {};

MessageView = Backbone.View.extend({

    initialize: function() {
        $.get('js/Test2Templates.tpl', function(doc) {

            var tmpls = $(doc).filter('template');

            templates['MessageView'] = [];

            tmpls.each(function() {
                templates.MessageView[this.id] = $.jqotec($.unescapeHTML(this.innerHTML));
            });
        });
    },

    render: function() {
        var tpldata = {name: 'Ville', thing: 'Finland'};
        $('#display').jqoteapp(templates.MessageView.greeting_template, tpldata);
    },

    events: {
        "click input[type=button]": "additionalTransactions"
    },

    additionalTransactions: function() {
        this.render();
    }

});

但是,我不想使用全局变量来定义“模板”,而是想在视图的初始化函数中创建“模板”,如下所示(但这样不起作用):

MessageView = Backbone.View.extend({

    view_templates: {},

    initialize: function() {
        $.get('js/Test2Templates.tpl', function(doc) {

            var tmpls = $(doc).filter('template');

            tmpls.each(function() {
                this.view_templates[this.id] = $.jqotec($.unescapeHTML(this.innerHTML));
            });
        });
    },

    render: function() {
        var tpldata = {name: 'Ville', thing: 'Suomi'};
        $('#display').jqoteapp(this.view_templates.greeting_template, tpldata);
    },

    events: {
        "click input[type=button]": "additionalTransactions"
    },

    additionalTransactions: function() {
        this.render();
    }

});

这可能相当简单和/或显而易见,但我在学习Backbone.js方面还处于某个阶段,非常感谢任何关于此的帮助!谢谢!

1个回答

17

您的view_templates实例变量是正确的(而且也是一个好主意)。您只需要确保在$.get()回调和tmpls.each()调用内部使用正确的this。我认为您希望您的initialize看起来更像这样:

initialize: function() {
    this.view_templates = { };

    var _this = this;
    $.get('js/Test2Templates.tpl', function(doc) {
        var tmpls = $(doc).filter('template');
        tmpls.each(function() {
            _this.view_templates[this.id] = $.jqotec($.unescapeHTML(this.innerHTML));
        });
    });
},

我不确定你想要在tmpls.each()中使用哪个this.id,但我猜你想要当前模板的DOM id属性,所以我将其保留为this.id

在你的构造函数(initialize)中,this.view_templates的赋值是必需的,因为你可能希望每个视图实例都有自己的数组副本。创建新的视图实例不会对视图进行深层复制,所以如果你只有:

MessageView = Backbone.View.extend({
    view_templates: {},
    // ...

如果这样做,所有的实例都将共享同一个view_templates对象,view_templates将更像是一个类变量而不是实例变量。

您可以在视图定义(即Backbone.View.extend()调用)中指定实例变量作为文档形式,但您需要在initialize方法中初始化任何应该作为实例变量的变量;只读或"类变量"如events可以保留为视图定义的一部分。


太好了!非常感谢您提供详细的答案!!我缺少的关键是(我没有尝试过的)var self = this;,然后在每个循环中使用'self'而不是'this'。有了这个,它就像预期的那样工作了。您能否详细说明为什么不能在循环内部使用'this'?'this'是否指当前循环实例(在每个循环内部)而不是视图实例?另外,正如您猜测的那样,'this.id'是指模板文件中模板的ID,就像这样:<template id="greeting_template"> ... </template> - Ville
@Ville:一个详尽的问题应该得到一个详尽的回答 :) .each 内部的 this 是当前的 DOM 元素,请查看 .each 的文档:http://api.jquery.com/each/ - mu is too short

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接