【发布时间】:2015-10-27 13:43:41
【问题描述】:
我是 Backbone.js 的新手,刚刚完成了创建“用户列表”系统 (https://www.youtube.com/watch?v=FZSjvWtUxYk) 的基本教程,其中所有模板、脚本等都是内联创建的。我让一切工作起来都很容易,所以我决定尝试模块化,因为我知道这是最好的做法。我正在遵循 AMD 方法 (https://cdnjs.com/libraries/backbone.js/tutorials/organizing-backbone-using-modules) 的本指南,除了一件事外,一切都正常工作 - 编辑用户时,“当前”数据没有加载到表单中。到目前为止,我在 SO 和其他地方发现的所有问题都已通过将模板生成代码放入 success: 回调 .fetch() 调用中来解决,但我已经这样做了。
代码如下:
(我忽略了处理 require.js 配置、路由器初始化等的 main.js 和 app.js。它们似乎工作得很好。)
// Filename: router.js
define([
'jquery',
'underscore',
'backbone',
'views/userList',
'views/editUser'
], function($, _, Backbone, UserListView, EditUserView){
var AppRouter = Backbone.Router.extend({
routes: {
'': 'home',
'new': 'editUser',
'edit/:id': 'editUser'
}
});
var initialize = function(){
var app_router = new AppRouter;
app_router.on('route:home', function(){
var userListView = new UserListView();
userListView.render();
});
app_router.on('route:editUser', function(id) {
var editUserView = new EditUserView();
editUserView.render({ id: id });
});
Backbone.history.start();
};
return {
initialize: initialize
};
});
views/editUser.js
// Filename: views/editUser
define([
'jquery',
'underscore',
'backbone',
'models/user',
'text!/templates/editUser.html'
], function($, _, Backbone, UserModel, rawEditUserTemplate) {
var userListView = Backbone.View.extend({
// Element to use for this view
el: $('.page'),
// Function to call when this view is rendered
render: function(options) {
var that = this;
// If there is an ID, we are editing
if ( options.id ) {
// Create the user, passing the ID
that.editUser = new UserModel({ id: options.id });
// Fetch the user data
that.editUser.fetch({
// When the fetch is returned
success: function(userData) {
// Generate the template and pass the data in
var editUserTemplate = _.template( rawEditUserTemplate );
that.$el.html(editUserTemplate({ user: userData }));
}
})
}
else { // We are creating a new user
// Generate the template with an empty user
var editUserTemplate = _.template( rawEditUserTemplate );
this.$el.html(editUserTemplate({ user: null }));
}
},
events: {
'submit .edit-user-form': 'saveUser',
'click .delete': 'deleteUser'
},
saveUser: function(e) {
e.preventDefault();
// Get the details
var userDetails = $(e.currentTarget).serializeObject();
// Create a user model
var user = new UserModel();
// Save the user details
user.save(userDetails, {
success: function(user) {
Backbone.history.navigate('', { trigger: true });
}
});
},
deleteUser: function(e) {
e.preventDefault();
// Destroy the user we are editing
this.editUser.destroy({
// When the destroy is finished
success: function() {
// Back to home
Backbone.history.navigate('', { trigger: true });
}
});
}
});
// Our module now returns our view
return userListView;
});
模板/editUser.html
<form class="edit-user-form">
<legend><%= user ? 'Update' : 'Create' %> User</legend>
<div class="form-group">
<label for="firstname">First Name</label>
<input type="text" class="form-control" name="firstname" id="firstname" value="<%= user ? user.get('firstname') : '' %>" />
</div>
<div class="form-group">
<label for="lastname">Last Name</label>
<input type="text" class="form-control" name="lastname" id="lastname" value="<%= user ? user.get('lastname') : '' %>" />
</div>
<div class="form-group">
<label for="age">Age</label>
<input type="text" class="form-control" name="age" id="age" value="<%= user ? user.get('age') : '' %>" />
</div>
<hr />
<button class="btn btn-success" type="submit"><%= user ? 'Update' : 'Create' %></button>
<% if ( user ) { %>
<input type="hidden" name="id" id="id" value="<%= user.id %>" />
<button class="btn btn-danger delete">Delete</button>
<% }; %>
</form>
使用此代码,无论我是在编辑还是创建,我都会得到一个空白的编辑表单,但是模板中的“创建”与“更新”文本开关工作正常。这意味着实际上正在传递一个用户对象,当我将 console.log(user) 添加到模板文件中时,它实际上是在向我显示用户数据。但是,当我记录 user.get('firstname') 或任何其他属性时,它会记录“未定义”。
【问题讨论】:
-
乍一看,它看起来很适合我。您确定返回的 JSON 响应包含属性吗?如果在成功回调中使用 console.log(userData.attributes) 会看到什么?
-
这是它记录的内容:i.imgur.com/wye24pA.png 这是正确的数据
-
不,那不是正确的数据。那是一个有 2 个键的对象:“0”和“id”,所有的属性都放在带有“0”键的对象中。您的响应 JSON 错误。
-
对不起,我的意思是实际的用户信息是正确的。所以你是说 API 给我的数据格式不正确?
-
是的。您的实际响应是一个带有 2 个键(“0”和“id”)的对象,但您需要一个带有“id”、“age”、“firstname”、“lastname”键的响应。
标签: javascript jquery backbone.js