I am attempting to refactor my backbone views to have all HTML related markup in external templates. Ideally I would like to have the element that the view is attached to in the external template as well. At the moment I have:
The html template
<h3 class="pull-left">Search</h3>
<input id="customer-search-input" class="input-large search-query" placeholder="Cust #, Name, Suburb or Owner" />
<button id="customer-search-show-all" class="btn pull-right">Show All</button>
<span id="update-time" class ="pull-right"></span>
<table id="customer-search-results-table" class="tablesorter tablesorter-dropbox">
<thead>
<tr>
<th>Customer Number</th>
<th>Customer Name</th>
<th>Suburb</th>
<th>Owner</th>
<th>Phone Number</th>
</tr>
</thead>
<tbody id="customer-list-results">
</tbody>
</table>
And the backbone view that consumes the template:
define(['jquery','underscore', 'backbone', 'text!templates/customerSearch.html','text!templates/customerRow.html', 'jquery.tablesorter' ],
function($, _, Backbone, customerSearchTemplate, customerRow) {
// ... Other sub-views
var CustomerSearch = Backbone.View.extend({
id:'customer-search', // would prefer to have these
className: 'well', // in the template
initialize: function(){
this.$el.html(customerSearchTemplate);
this.customerSearchInput = this.$("#customer-search-input");
},
events: {
"click #customer-search-show-all": "showAll",
"keyup #customer-search-input": "search"
},
search: function(){
var filteredCustomers = this.collection.search(this.customerSearchInput.val(), ['id','companyName','suburb','businessContact']);
this.customerSearchResultsView = new CustomerSearchResultsView({collection: filteredCustomers});
this.customerSearchResultsView.render();
},
showAll: function() {
this.customerSearchResultsView = new CustomerSearchResultsView({collection: this.collection});
this.customerSearchResultsView.render();
}
});
return CustomerSearch;
});
Everything works but it would be great to be able to have the id
and className
as part of a wrapper div in the template. If I add this to the template then it appears correctly when rendered but is wrapped by another div by the backbone view.
I'm trying to decouple everything as much as possible.
Thanks!
Update 17 Oct 2012
Using the view.setElement
method
var CustomerSearch = Backbone.View.extend({
template:_.template(customerSearchTemplate),
initialize: function(){
this.setElement(this.template());
},
// ...
});
with template
<div id="customer-search" class="well">
<h3 class="pull-left">Search</h3>
// ...
</div>
appears to work. Just wondering now if there is performance hit. Will report back.