问题
Consider following Scenario:-
- Model of a Player
var Player = Backbone.Model.extend({
defaults: {
PlayerId: 0,
PlayerName: "",
IsActive: false
}
});
Collection Model is as follows:
var PlayerList = Backbone.Collection.extend({
model: Player,
url: '/Match/GetPlayers/'
});
List View is as follows:
var ListView = Backbone.View.extend({
el: '#ListContainer',
initialize: function () {
_.bindAll(this, 'render');
this.collection.on('reset', this.render);
},
render: function () {
if (this.collection.length > 0) {
this.collection.each(this.AppendPlayer, this);
}
return this;
},
AppendPlayer: function (data) {
var palyerView= new PlayerView({ model: data });
$(this.el).find('table').append(genreView.render().el);
},
events: {
"click #btnplay": "CheckStatus"
},
CheckStatus: function () {
// alert();
//here i will make a ajax call and get update the status of player
which comes from other REST service.
}
});
Below is the PlayerView:
var PlayerView = Backbone.View.extend({
tagName: "tr",
template: _.template($("#player-Template").html()),
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
HTML is as follows:
<div id="ListContainer">
<input type="button" id="btnplay" value="StatusCheck" />
<table id="myTable">
<tr>
<td>Player Id</td>
<td>Name</td>
<td>Statu</td>
</tr>
</table>
</div>
<br />
<br />
<script id='player-Template' type='text/template'>
<td><%=PlayerId%></td>
<td><%=PlayerName%></td>
<td><%=IsActive%></td>
</script>
so when i click the "Play" button it calls my API service and gets me an updated collection.
and i try to refresh the collection and the view using below logic:
PlayerList.fetch({
success: function (collection, resp) {
//console.log('success' + resp); //
},
error: function (er) {
console.log('error: %o', er)
},
reset: true,
});
I get the updated model back but what happen is the updated model get's appended with the existing rows.
I need to clear the existing rows and repopulate it with my new collection.
Any help would be great.
回答1:
empty() the table inside the render method:
render: function () {
this.$el.find('table').empty(); // clears existing rows
if (this.collection.length > 0) {
this.collection.each(this.AppendPlayer, this);
}
return this;
}
BTW, you don't have to do $(this.el)
, backbone provides a jQuery instance of your view's element via this.$el
.
Unless you're reusing the AppendPlayer
(I suggest using camelCase for method names. Use pascal case only for constructor functions) method, you can simply do the following:
render: function() {
var $table = this.$el.find('table');
$table.empty();
if (this.collection.length) {
this.collection.each(function(model) {
$table.append(new PlayerView({
model: model
}).render().el);
});
}
return this;
}
and if you modify the playerView to render itself as shown below:
var PlayerView = Backbone.View.extend({
tagName: "tr",
template: _.template($("#player-Template").html()),
initialize: function() {
this.render();
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
You can just do:
render: function() {
var $table = this.$el.find('table');
$table.empty();
if (this.collection.length) {
this.collection.each(function(model) {
$table.append(new PlayerView({
model: model
}).el);
});
}
return this;
}
Side note: you seems to be creating palyerView
but you're appending genreView
..?!
来源:https://stackoverflow.com/questions/34268164/refresh-the-table-view-on-collection-fetch-method