簡體   English   中英

我如何使下划線模板彼此交互?

[英]How can I make underscore templates interact with each other?

我的Backbone.js項目中有兩種模板。 單項模板和項列表模板。

此外,項目中有兩種視圖類型:單項模板和項列表。

我使用RequireJS來使應用程序模塊化。 因此,我想,將模板也分開也是一個好習慣。 但是有一個問題:我無法使我的模板進行“交流”。 呈現CollectionView時,它在頁面中僅包含一個元素-空的<ul id="spaceman-list">並且其中沒有任何項目集合。 在我的列表視圖中,我使用addItem函數通過itemView包裝每個集合項,但是它不起作用。 該列表只是不在dom中呈現。

我不想使用_.each()這樣的混亂東西,我想保持代碼干凈。

這是兩個視圖的代碼:列表視圖

// app/js/views/spaceman-list.js

'use strict';

(function(w) {

    define([
        'jquery',
        'underscore',
        'backbone',
        '../models/spaceman',
        '../views/spaceman-item',
        '../collections/spaceman-collection',
        'text!../templates/spaceman-list.html'
    ], function($, _, Backbone, SpacemanModel, SpacemanItemView, SpacemanCollection, listTemplate) {
            var SpacemanListView = Backbone.View.extend({
                el: '#container',
                render: function() {
                    this.collection.on('reset', this.addItem, this);
                    this.collection.each(this.addItem, this);
                    var data = {
                        spacemen: this.collection.models
                    };
                    var compiled = _.template(listTemplate, data);
                    this.$el.html(compiled);
                    return this;
                },
                addItem: function(item) {
                    var newSpaceman = new SpacemanItemView({model: item});
                    this.$el.find('ul').append(newSpaceman.render());
                }
            });
            return SpacemanListView;
    });

   })(window);

和項目視圖:

  // app/js/views/spaceman-item.js
 'use strict';

 (function(w) {

    define([
        'jquery',
        'underscore',
        'backbone',
        '../models/spaceman',
        'text!../templates/spaceman-item.html'
    ], function($, _, Backbone, SpacemanItem, itemTemplate) {
            var SpacemanItemView = Backbone.View.extend({
                el: '#spaceman-list',
                render: function() {
                    var data = {
                        spaceman: this.model
                    };
                    this.$el.html(_.template(itemTemplate, data));
                },
            });
            return SpacemanItemView;
    });

 })(window);

而且,正如我在上文所述,我將下划線模板分開放置:這是列表模板:

// app/js/templates/spaceman-list.html
<ul id="spaceman-list"></ul>

這是項目模板:

// app/js/templates/spaceman-item.html
<li><% spaceman.get('name') %></li>

另外,我在這里添加我的應用程序入口點:

// app/js/application.js
'use strict';

(function(w) {
   define([
   'jquery',
   'underscore',
   'backbone',
   'collections/spaceman-collection',
   'views/spaceman-list'
   // Request router.js
   ], function($, _, Backbone, ItemsList, ListView) {
        var App = Backbone.View.extend({
                initialize: function(){
                // Pass in our Router module and call it's initialize function
                console.log('Yeeha!');
                var endurance = new ItemsList([
                                {name: 'Cooper'},
                                {name: 'Brend'},
                                {name: 'Romilly'},
                                {name: 'Doyle'},
                                {name: 'Mann'}
                            ]);

                console.log(endurance);

                    var view = new ListView({collection:endurance});

                    view.render();
                }
          });

            return App;
   });

})(window);

我只是為此而瘋狂。 如何制作單獨的模板以彼此“看到”?

您在SpacemanListView#addItem這樣說:

this.$el.find('ul').append(newSpaceman.render())

SpacemanItemView#render不返回任何內容:

render: function() {
    var data = {
        spaceman: this.model
    };
    this.$el.html(_.template(itemTemplate, data));
},

SpacemanItemView還說:

el: '#spaceman-list'

因此,當所有SpacemanItemView實例的render函數都說this.$el.html(...)時,它們將嘗試使用相同的el 大概您的templates/spaceman-list.html包含<ul id="spaceman-list">或類似的內容,因此#spaceman-list將集合視圖放置在頁面上之前不會解析為任何內容; 但您是在頁面上的集合視圖之前調用addItem ,因此所有項目視圖都試圖呈現為同一不存在的元素。

解決方案是雙重的:

  1. render函數通常return this; 以便調用者可以$container.append(view.render().el)將內容放到頁面上,因此可以這樣做。
  2. 使用預定義的el (即, el: '#something'視圖定義中的el: '#something' )會導致各種排序和事件問題,當每個視圖創建並擁有自己的el時,效果會更好。

addItem應該看起來像這樣:

addItem: function(item) {
    var newSpaceman = new SpacemanItemView({model: item});
    this.$('ul').append(newSpaceman.render().el);
}

請注意this.$快捷方式和append調用中的.el

然后我們重新處理項目視圖:

var SpacemanItemView = Backbone.View.extend({
    tagName: 'li',
    render: function() {
        var tmpl = _.template(itemTemplate);
        this.$el.html(tmpl({ spaceman: this.model }));
        return this;
    },
});

沒有更多的el但是現在我們有了tagName: 'li' ,這將告訴Backbone創建一個空的<li>作為視圖的el el文檔介紹了如何使用各種視圖屬性來確定el將是什么。

還要注意_.template(tmpl, data)形式在_.template 1.7.0中停止工作,因此我也修復了該問題。

您還可以調整templates/spaceman-item.html模板,使其僅作為<li>的內容:

<% spaceman.get('name') %>

我建議對集合視圖進行類似的更改,以便它也創建並擁有它的el

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM