2017-03-21 133 views
0

我正在學習Backbone和Underscore,現在我正在製作一個小模擬電子郵件應用程序。呈現多個模板

我設法將JSON電子郵件集合傳遞給我的視圖,並將其顯示在無序列表中。我想要的是點擊一個項目,並在顯示電子郵件內容的列表旁邊顯示一個單獨的模板。

代碼從我的觀點片段:

的HTML模板:

<div> 
    <h1>Backbone test data bind to view</h1> 
    <hr/> 
    <div class="page"> 
    </div> 
    <div class="content"> 
    </div> 
</div> 

<script type="text/template" id="email-list-template-styled">  
<div class="tab"> 
    <ul> 
     <@ _.each(emails, function(email){ @> 
      <a class="tablinks" data-id="<@= email.get('id') @>" href="backbone" > 
       <td> From: <@= email.get('sender') @> </td> </br> 
       <td> To: <@= email.get('recipient') @> </td> </br> 
       <td> Date: <@= email.get('dateSent') @> </td> </br> 
      </a> 
     <@ }) @> 
    </ul> 
</div> 
</script> 

<script type="text/template" id="email-content"> 
    <div id="emailContent" class="tabcontent"> 
     <h3>From: sender</h3> 
     <h3>To: recipient</h3> 
     <h3>Subject: subject</h3> 
     <h3>Date: dateSent</h3> 
     <p>message</p> 
    </div> 
</script> 

的Java腳本:

<script type="text/javascript"> 
var EmailsList = Backbone.Collection.extend({ 
    url : 'backbone/getEmails.html' 
}); 

var Email = Backbone.Model.extend({}); 

var EmailList = Backbone.View.extend({ 
    el: '.page', 
    events: { 
     'click' : 'showAlert' 

     }, 
     showAlert: function(e){ 
      e.preventDefault(); 
      var that = this; 
      var id = $(event.target).data('id'); 
      var Email = Backbone.Model.extend({ 
       url: 'backbone/getEmail/' + id 
      }); 

      var email = new Email(); 
      email.fetch({ 
       success: function(email){ 
        console.log(email.toJSON()); 
        var template = _.template($('#email-content').html(), {email: email.models}); 
        that.$el.append(template); 
       } 
      }) 
     }, 

    render: function(){ 
     var that = this; 
     var emails = new EmailsList(); 
     emails.fetch({ 
      success : function(emails) { 
       console.log(emails.toJSON()); 
       var template = _.template($('#email-list-template-styled').html(), {emails: emails.models}); 
       that.$el.html(template); 
      } 
     }) 
    } 
}); 

var emailList = new EmailList(); 

var Router = Backbone.Router.extend({ 
    routes:{ 
     '': 'backbone' 
    } 
}) 

var router = new Router(); 
router.on('route:backbone', function(){ 
    emailList.render(); 
}); 

Backbone.history.start(); 
</script> 

單個對象的數據例如:

dateSent:"2017-03-21 08:36" 
id:3 
message:"Message3" 
recipient:"Recipient3" 
sender:"Sender3" 
subject:"Subject3" 

到目前爲止,我已經設法得到了我點擊點擊事件的電子郵件ID。 比我試圖渲染一個模板傳遞單個電子郵件對象(我收到正確的電子郵件JSON),我附加模板,因此它創建多個實例,我似乎無法獲得變量打印在email-content模板。我得到一個錯誤:Uncaught TypeError: Cannot read property 'get' of undefined當我像鍵入:

<h3>From: sender <@= email.get('sender') @></h3> 

所以問題是:

我怎樣才能重新呈現內容的模板

如何訪問電子郵件變量內容模板?

回答

2

你的代碼是用舊underscore.js版本的語法,如果你使用新版本,那麼這是一個問題,使用新的語法:

var template = _.template(templateString); 
template(data); 

,並在下面的一行:

var template = _.template($('#email-content').html(), {email: email.models}); 

電子郵件是一個模型,而不是一個集合。

所以,你的代碼應該是:

var template = _.template($('#email-content').html(), {email: email}); 

現在,您將能夠做到<h3>From: sender <@= email.get('sender') @></h3>

我建議做:

var template = _.template($('#email-content').html(), {email: email.toJSON()}); 

和渲染像<h3>From: sender <@= email.sender @></h3>只是爲了確保模板的東西不會影響原來的模式。


而且,你不應該在一個事件處理程序

var Email = Backbone.Model.extend({ 
    url: 'backbone/getEmail/' + id 
}); 

定義模式構造相反這樣定義

var Email = Backbone.Model.extend({ 
    urlRoot: 'backbone/getEmail/' 
}); 

模型,並在模型上設置id。主幹將附加idurl

設置urlRoot如果你通過{model: Email}收集,並使用它比所有的時間,這是正確的方式做到這一點IMO創建新模型實例get()方法發現從集合中匹配模型是沒有必要的。

其他建議:

  • 定義一個單獨的視圖電子郵件的詳細視圖
  • 避免使用el財產,如果你是新來的骨幹
  • 升級到underscore.js新版本和高速緩存模板查看功能template屬性
  • 使事件偵聽器'click' : 'showAlert'更具體,如'click .email' : 'showAlert'。否則,單擊視圖中的任何位置都會觸發處理程序。如果用戶點擊數據不是id(如下拉菜單等)的實際電子郵件,則會導致錯誤
+0

感謝您的回答。從電子郵件中刪除.models幫助。我現在能夠顯示數據。 移動電子郵件從事件 '變種電子郵件= Backbone.Model.extend({ \t urlRoot:「骨幹/ getEmail /」 });' – mindz

+0

如果我定義的細節如何傳遞的不同視圖選擇電子郵件到視圖? – mindz

+0

@mindz'showAlert:function(e){this.emailView = new EmailView({model:model})}'。您可以將EmailView'el'附加到EmailListView'el'或某個特定的容器。您甚至可以使用EmailListView觸發器和事件,如'this.trigger('show-email',{id:id});'並從您的應用程序的其他位置收聽它,並使用事件數據中的模型ID初始化EmailDetailView –