我有一个simle CRUD应用程序。但是当我删除时,创建或编辑第N次N号请求被触发。
例如,如果我第三次创建用户,则会触发3 POST请求。
当我刷新页面时,只触发一个请求。请帮忙。下面是我的代码。
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My App</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>User Manager</h1>
<hr />
<div class="page"> </div>
</div>
<script src="http://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="http://underscorejs.org/underscore-min.js" type="text/javascript"></script>
<script src="http://backbonejs.org/backbone-min.js" type="text/javascript"></script>
<script type="text/javascript">
function htmlEncode(value){
return $('<div/>').text(value).html();
}
</script>
<script type="text/template" id="user-list-template">
<a href="#/new" class="btn btn-primary">New</a>
<hr />
<table class="table striped">
<thead>
<tr>
<th>First Name</th><th>Last Name</th><th>Age</th><th></th>
</tr>
</thead>
<tbody>
<% _.each(users, function(user) { %>
<tr>
<td><%= htmlEncode(user.get('firstname')) %></td>
<td><%= htmlEncode(user.get('lastname')) %></td>
<td><%= htmlEncode(user.get('age')) %></td>
<td><a class="btn" href="#/edit/<%= user.id %>">Edit</a></td>
</tr>
<% }); %>
</tbody>
</table>
</script>
<script type="text/template" id="edit-user-template">
<form class="edit-user-form">
<legend><%= user ? 'Edit' : 'New' %> User</legend>
<label>First Name</label>
<input name="firstname" type="text" value="<%= user ? user.get('firstname') : '' %>">
<label>Last Name</label>
<input name="lastname" type="text" value="<%= user ? user.get('lastname') : '' %>">
<label>Age</label>
<input name="age" type="text" value="<%= user ? user.get('age') : '' %>">
<hr />
<button type="submit" class="btn"><%= user ? 'Update' : 'Create' %></button>
<% if(user) { %>
<input type="hidden" name="id" value="<%= user.id %>" />
<button data-user-id="<%= user.id %>" class="btn btn-danger delete">Delete</button>
<% }; %>
</form>
</script>
<script src="user.js" type="text/javascript"></script>
</body>
</html>
JAVASCRIPT
var Myapp ={};
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.url = 'http://backbonejs-beginner.herokuapp.com' + options.url;
});
// Setting up user collection
Myapp.Users = Backbone.Collection.extend({
url: '/users'
});
// setting up user model
Myapp.User = Backbone.Model.extend({
urlRoot: '/users',
validate: function(attrs, options) {
if (attrs.firstname =='') {
alert("First Name cannot be blank.");
return "First Name cannot be blank.";
}
}
});
// setting up routes
Myapp.Router = Backbone.Router.extend({
routes: {
"": "home",
"edit/:id": "edit",
"new": "edit",
}
});
Myapp.router = new Myapp.Router;
Myapp.router.on('route:home', function() {
// render user list
Myapp.displayUsersModule.init().render();
})
Myapp.router.on('route:edit', function(id) {
Myapp.editUserViewModule.init().render({id: id});
})
// display user module imkplemented in module patern. The only public api is the init function
Myapp.displayUsersModule = (function(){
var UserListView = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var users = new Myapp.Users();
users.fetch({
success: function (users) {
var template = _.template($('#user-list-template').html(), {users: users.models});
that.$el.html(template);
},
error: function (model, xhr, options) {
alert("Something went wrong while fetching details");
}
})
}
});
var init = function() {
userListView = new UserListView();
return userListView;
};
return {
init: init
};
})();
// edit and delete user module imkplemented in module patern. The only public api is the init function
Myapp.editUserViewModule = (function(){
var UserEditView = Backbone.View.extend({
el: '.page',
events: {
'submit .edit-user-form': 'saveUser',
'click .delete': 'deleteUser'
},
saveUser: function (ev) {
var userDetails = $(ev.currentTarget).serializeObject();
var user = new Myapp.User();
user.save(userDetails, {
success: function (user) {
Myapp.router.navigate('', {trigger:true});
},
error: function (model, xhr, options) {
alert("Something went wrong while saving details");
}
});
return false;
},
deleteUser: function (ev) {
alert(1);
this.user.destroy({
success: function () {
console.log('destroyed');
Myapp.router.navigate('', {trigger:true});
},
error: function (model, xhr, options) {
alert("Something went wrong while Deleting user");
}
});
return false;
},
render: function (options) {
var that = this;
if(options.id) {
that.user = new Myapp.User({id: options.id});
that.user.fetch({
success: function (user) {
var template = _.template($('#edit-user-template').html(), {user: user});
that.$el.html(template);
}
})
} else {
var template = _.template($('#edit-user-template').html(), {user: null});
that.$el.html(template);
}
}
});
var init = function() {
var userEditView = new UserEditView();
return userEditView;
};
return {
init: init
};
})();
$(document).ready(function(){
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
Backbone.history.start();
});
答案 0 :(得分:0)
问题在于,在切换时你不会纠正解除绑定的视图,因此你有多个zombie视图可以监听相同的DOM事件(这是因为你使用el: 'selector'
样式将它们附加到DOM不是很好)。
要解决此问题,您应该在不再需要时调用remove(或undelegateEvents
)方法。
或者您可以使用可帮助您管理视图的库,例如: