在Underscore模板中调用变量

时间:2015-01-02 04:11:16

标签: backbone.js underscore.js underscore.js-templating

我试图在我的Backbone应用程序中创建一个Underscore模板,但是我的范围必须关闭或者其他东西,因为Underscore认为我的变量没有定义。我得到" Uncaught ReferenceError:未定义字典。"

以下是模板代码:

<script type="text/template" id="new_template">
        <table class="table striped">
            <tbody>
                <% _.each(dictionary, function(user){ %>
                    <tr>
                        <td> <%= user.get('word')%></td>
                        <td> <%= user.get('definition')%></td>
                    </tr>
                <% }) %>
            </tbody>
        </table>
</script>

以下是app.js中定义我的内联模板变量调用的逻辑:

(function($){


        //---------SINGLE ENTRY MODEL----------
            var Entry = Backbone.Model.extend({
                defaults: function(){
                    return{
                        word: '',
                        definition: ''
                    }
                }
            });

        //------------ENTRY MODEL COLLECTION------------
        EntryList = Backbone.Collection.extend({

                model: Entry
            });

        //-----INSTANCIATE COLLECTION----
        var dictionary = new EntryList();
        var saved = new EntryList();


        //-----SINGLE ENTRY VIEW------
        var EntryView = Backbone.View.extend({
            model: new Entry(),
            tagName:'div',
            className: 'singleEntry',

            events:{
                'click .edit': 'edit',
                'click .delete': 'delete',
                'keypress .definition': 'updateOnEnter',
                'click .save': 'save'
            },

            initialize: function(){
                // this.template = _.template($("#dictionary_template").html());
                this.template = _.template($("#new_template").html());

            },

            delete: function(ev){
                ev.preventDefault;
                dictionary.remove(this.model);
                saved.remove(this.model);

            },

            edit: function(ev){
                ev.preventDefault;
                this.$('.definition').attr('contenteditable', true).focus();

            },

            save: function(ev){
                ev.preventDefault;
                saved.add(this.model);
                dictionary.remove(this.model);
                saved.comparator = 'word';
                console.log(this.model.toJSON());

            },

            close: function(){
                var definition = this.$('.definition').text();
                this.model.set('definition', definition);
                this.$('.definition').attr('contenteditable', false).blur();

            },

            updateOnEnter: function(ev){
                if(ev.which == 13){
                    this.close();
                }
            },

            render: function(){
                this.$el.html(this.template(this.model.toJSON()));
                return this;
            }
        });

        //--------------DICTIONARY VIEW------------
        var DictionaryView = Backbone.View.extend({
            model: dictionary,
            el: $('#entries'),

            initialize: function(){
                this.model.on('add', this.render, this);
                this.model.on('remove', this.render, this);

            },

            render: function(){
                var self = this;
                self.$el.html('');
                _.each(this.model.toArray(), function(entry, i){
                    self.$el.append((new EntryView({model: entry})).render().$el);
                });

                return this;
            }
        });

        //---------SAVED ENTRY VIEW-----------
        var SavedView = Backbone.View.extend({
            model: saved,
            el: $('#saved'),

            initialize: function(){
                this.model.on('add', this.savedRender, this);
                this.model.on('remove', this.savedRender, this);

            },

            savedRender: function(){
                var self = this;
                self.$el.html('');
                _.each(this.model.toArray(), function(entry, i){
                    self.$el.append(new EntryView({model: entry}).render().$el);
                });

                return this;
            }
        });

        //---------TEST VIEW------------------
        var TestView = Backbone.View.extend({
            el: $('#saved'),

            render: function(){
                this.$el.html('new event route');
            }
        });


        //-------BINDING DATA ENTRY TO NEW MODEL VIEW-------
        $(document).ready(function(){
            $('#new-entry').submit(function(ev){
                var entry = new Entry({word: $('#word').val(), definition: $('#definition').val() });

                dictionary.add(entry);
                dictionary.comparator = 'word';

                console.log(dictionary.toJSON());

                $('.form-group').children('input').val('');

                return false;
            });

            var appView = new DictionaryView();
            var savedView = new SavedView();
        });


        //--------------ROUTER----------------
        var Router =  Backbone.Router.extend({
            routes:{
                '':'home',
                'new': 'newEvent' 
            }
        });
        var router = new Router();
        router.on('route:home', function(){
            console.log('router home');
        router.on('route:newEvent', function(){
            console.log('router new');
            var testView = new SavedView();
            })
        });
        Backbone.history.start();

    })(jQuery);

1 个答案:

答案 0 :(得分:0)

更新

Underscore模板的工作方式(一旦编译它们)就是将ERB样式分隔符中找到的任何非JavaScript关键字(蜜蜂:&lt; %%&gt;)替换为传入的对象中的值编译的模板。在示例代码中,Underscore期望一个对象具有名为'dictionary'的属性,例如。

您现在正在设置模板的方式,它期望具有EntryListwords属性的模型集合(definition)。但是,如果你查看你的代码,

render: function(){
  this.$el.html(this.template(this.model.toJSON()));
    return this;
}

是唯一一次在Entry视图中填充模板,该视图不包含集合,而是Entry模型。

你真正想要做的是摆脱模板中的for each循环,让它简单地渲染模型。我会像这样重写它,

<script type="text/template" id="new_template">
    <tr>
      <td> <%= word %></td>
      <td> <%= definition %></td>
    </tr>
</script>

现在,我希望字典视图中的el<tbody>。如果是,那么这些模型会轻松地将<tr>停放在他们必须去的地方,你可以称它为一天。


查看Entry模型的默认值,看起来您将使用{ word: '', definition: '' }填充该模型。在您的模板中,下划线正在查找名为dictionary的变量。然而,您将具有变量worddefinition的对象传递给模板。

更重要的是,我不确定您的视图构建逻辑是否具有竞争意义。您正在EntryView中的DictionaryView之外构建子视图,然后在模板中运行for each循环?