<!DOCTYPE HTML>
<html>
<head>
<title></title>
<link href="/bundles/hoaxpartner/css/style.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div id="header">Backbone</div>
<div id="sidebar"></div>
<div id="content"></div>
<script type="text/template" id="tpl-user-list-item">
<a href='#users/<%= id %>'><%= name %></a>
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script>
window.User = Backbone.Model.extend();
window.UserCollection = Backbone.Collection.extend({
model: User,
url: "/app_dev.php/api/users/1/",
parse : function(resp) {
/*
$.each(resp.users, function(key1, value1) {
resp.users[key1] = $.map(value1, function(value2, key2) {
return [value2];
});
});
*/
return resp.users;
},
});
// Views
window.UserListView = Backbone.View.extend({
tagName:'ul',
initialize:function () {
this.model.bind("reset", this.render, this);
},
render:function (eventName) {
_.each(this.model.models, function (user) {
$(this.el).append(new UserListItemView({model:user}).render().el);
}, this);
return this;
}
});
window.UserListItemView = Backbone.View.extend({
tagName:"li",
template:_.template($('#tpl-user-list-item').html()),
render:function (eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
// Router
var AppRouter = Backbone.Router.extend({
routes:{
"":"list"
},
list:function () {
this.userList = new UserCollection();
this.userListView = new UserListView({model:this.userList});
this.userList.fetch();
$('#sidebar').html(this.userListView.render().el);
}
});
$(function() {
var app = new AppRouter();
Backbone.history.start();
});
</script>
</body>
</html>
/app_dev.php/api/users/1 call output:
{
"users": [
{
"userid": "Jf9CEy70",
"password": "g5JY9OB2",
"status_id": 1,
"created": "2014-01-13 18:33:25"
},
{
"userid": "8LZVQX6b",
"password": "QFzO92tM",
"status_id": 1,
"created": "2014-01-13 18:35:00"
},
{
"userid": "cItWduq9",
"password": "SuzcWisl",
"status_id": 0,
"created": "2014-01-13 18:35:21"
}
]
}
The data is received from "/app_dev.php/api/users/1" API, but I'm stuck on displaying it.
1- Try to add this function to your collection :
parse : function(resp) {
return resp.users;
}
Because your collection is waiting an array of models, but it gets an object.
2- Change this ligne this.collection.on('change', this.render, this);
by this one this.collection.on('reset', this.render, this);
, because when the collection receive the data from the server it trigger a reset
event (it's the Model that trigger change
)
3- Add this line
this.collection = new App.Collections.Models();
before this line
view = new App.Views.ModelsIndex({'collection': this.collection});
Because you are using this.collection
without initializing it.
4- Change the tagName
in your App.Views.ModelsIndex
to el
and give it the div where you want your template to be rendered ( '#someEl'
)
Your new problem is the template, you have some errors in it (userId instead of id, there is no name in your json), here is a working one :
<script type="text/template" id="tpl-user-list-item">
<a href = '#users/<%= userid %>' ><%= created %></a>
</script>
Because this.collection.fetch();
is asynchronous, so if you call it in initialize
and then call index
immediately, the collection at this time is not "fetched" yet. You should change your code to properly handle asynchronous calls
Another thing is that you are listening to change
event which is applied when there are changes for each model in the collection, you should listen to reset
event (if you want to reset the model after fetching) or sync
(if I remember correctly)
Another event that might be useful is request
which will be fired as soon as the ajax request is sent
Updated: So in this case, you can change
this.collection.on('change', this.render, this);
to
this.collection.on('sync', this.render, this);
And move
this.collection.fetch();
To after
view = new App.Views.ModelsIndex({'collection' : this.collection});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.