2013-03-16 38 views
0

在過去,我一直在做的是當我想渲染和顯示一個模板的集合只是調用集合上的「each」方法。對於每個模型,我爲每個模型創建一個新的單一視圖並將其附加到$ el。但在這種情況下,這是行不通的。我有一個輸入類型的文本在我的模板中,我不想爲每個模型顯示一個新的輸入。我寧願以某種方式將集合傳遞給模板並遍歷模板中的集合。另外值得一提的是,我的收藏是通過我的主要應用程序視圖傳遞時,在創建這個觀點的一個新實例:如何將backbone.js集合傳遞給視圖並遍歷集合,然後渲染視圖?

// clientsview.js 

define(
[ 
    'backbone', 
    'ClientView', 
    'Clients' 
], function(Backbone, ClientView, Clients) { 

ClientsView = Backbone.View.extend({ 

    tagName: '#page', 
    template: _.template($('#allClientsTemplate').html()), 


    initialize: function() { 
     this.render(); 
    }, 

    render: function() { 

     // var that = this; 
     console.log('collection'); 
     console.log(this.collection);// successfully returns collection 
     console.log('template'); 
     console.log(this.template);// successfully returns template function 


     // This causes an error: 
     //Uncaught TypeError: Cannot call method 'toJSON' of undefined 
     var tmpl = this.template({ clients: this.collection.toJSON() }); 

     return this; 

    } 

}); 
return ClientsView; 
}); 

我在index.html的模板

// index.html 
<script id="allClientsTemplate" type="text/template"> 
// I do not want create an input for every single model 
// but I need the input to be part of the view. 
<input type="text" class="table-search" id="search" autocomplete="off" placeholder="Search Clients…"> 
<table class="table" id="tblData"> 
    <thead> 
     <tr> 
      <th>First Name</th> 
      <th>Last Name</th> 
      <th>Status</th> 
     </tr> 
    </thead> 
    <tbody id="tblDataBody"> 

     <% _.each(clients, function(client) { %> 

      <tr> 
       <td><a href=""><%- client.first_name %></a></td> 
       <td><a href=""><%- client.last_name %></a></td> 
       <td><a href=""><%- client.status %></a></td> 
      </tr> 

     <% }); %> 

    </tbody> 
</script> 

我我的實例客戶從我的主要的應用程序視圖中查看:

define(
    [ 
     'jquery', 
     'underscore', 
     'backbone', 
     'AddClientView', 
     'ClientsView', 

    ], function($, _, Backbone, AddClientView, ClientsView) { 

    AppView = Backbone.View.extend({ 

     initialize: function() { 

      // var addClientView = new AddClientView({ collection: this.collection }); 
      var clientsView = new ClientsView({ collection:this.collection }); 


     } 

    }); 
    return AppView; 
}); 

而且我從我的初始化方法實例我主要的應用程序視圖:

define('App', [ 
    'jquery', 
    'underscore', 
    'backbone', 
    'Router', 
    'bootstrap', 
    'Clients', 
    'AppView' 
], function($, _, Backbone, Router, bootstrap, Clients, AppView) { 

    function initialize() { 

     // for custom global events 
     window.vent = _.extend({}, Backbone.Events) 

     var app = new Router(); 
     Backbone.history.start(); 


     // probably more appropriate to do this in app view 
     var clients = new Clients;// Get collection of clients 


     clients.fetch().then(function() {// fetch client collection from db 
      new AppView({ collection: clients }); 
     }); 

    } 
    return { 
     initialize: initialize 
    }; 
}); 

我的初始化方法正在從main.js稱爲:

// main.js 
require.config({ 
    shim: { 
     'underscore': { 
     exports: '_' 
     }, 
     'backbone': { 
      deps: ['underscore', 'jquery'], 
      exports: 'Backbone' 
     }, 
     'bootstrap': { 
      deps: ['jquery'], 
      exports: 'bootstrap' 
     } 
    }, 
    paths: { 
     'text'   : 'lib/require/text', 
     'jquery'  : 'lib/jquery/jquery-1.9.1', 
     'underscore' : 'lib/underscore/underscore', 
     'backbone'  : 'lib/backbone/backbone', 
     'bootstrap'  : 'lib/bootstrap/bootstrap', 
     'App'   : 'app', 
     'Router'  : 'router', 
     'AppView'  : 'views/app/appview', 
     'Client'  : 'models/clients/client', 
     'Clients'  : 'collections/clients/clients', 
     'ClientView' : 'views/clients/clientview', 
     'ClientsView' : 'views/clients/clientsview', 
     'AddClientView' : 'views/clients/addclientview' 
    } 
}); 
require(['App'], function(App) { 
    App.initialize(); 
}); 

我得到一個錯誤,當我嘗試這種方法(遺漏的類型錯誤:無法調用方法的不確定「的toJSON」)。我該如何做這項工作?

+0

是如何你實例化ClientsView?你是否將'collection'選項傳遞給'新的ClientsView(...)'? – 2013-03-16 23:13:15

+0

@StuartM斯圖爾特,看看我的更新。我添加了更多代碼來嘗試並幫助解釋我在這裏做的事情。希望這可以幫助。 – Scott 2013-03-16 23:22:18

+1

爲什麼ClientsView和AppView全局變量?你的'toJSON'錯誤來自哪裏?順便說一句,'console.log'是可變的,所以你可以說'console.log(a,b,c)'。 – 2013-03-16 23:55:25

回答

2

你必須初始化你的收藏,添加項目,然後實例化視圖,並通過收集到它:

var clients= new Clients(); 
clients.add({FirstName: 'Joe', LastName: 'Blow', Status: 'Active' }); 

var clientsView = new ClientsView({collection: clients}); 

您還需要更改模板:

<% _.each(collection, function(client) { %> 
<tr> 
    <td><a href=""><%- client.get('FirstName') %></a></td> 
    <td><a href=""><%- client.get('LastName') %></a></td> 
    <td><a href=""><%- client.get('Status') %></a></td> 
</tr> 
<% }); %> 
+0

如果你看看我的文章中的第四個代碼塊,我將實例化我的集合並調用其上的獲取方法來獲取數據庫中的所有項目。而他們我把這個集合傳遞給我的appview,然後從那裏傳遞給我的clientsview。 – Scott 2013-03-16 23:32:03

+0

@Scotty,你能否確認 1 - console.log(這個。可以使用「that」而不是「this」: var tmpl = this.template({clients:** that。。collection.toJSON())這個集合中不包含任何未定義的對象, }); – hnafar 2013-03-17 00:00:16

0

你骨幹是正確的。在這裏你的問題是,你沒有通過獲取創建的承諾傳遞數據,當您實例化APPVIEW:

代碼:

clients.fetch().then(function() {// fetch client collection from db 
    new AppView({ collection: clients }); 
}); 

它應該是:

clients.fetch().then(function(resp) {// fetch client collection from db 
    new AppView({ collection: resp.data }); 
});