This is an example of a user list and user information display. It is simple, but this is not the focus. It focuses on learning how to use Backbone. First, let's take a look:
1. Default Screen
2. Add (modify) User Images
3. User details
The following is the implementation of this small item:
Backbone itself does not have the DOM operation function, so we certainly cannot leave DOM operations. Here we choose powerful jquery, and of course we can choose other libraries such as zepto and ender, in addition, Backbone depends on another well-known underscore library. for convenience, no background program is written here. The localstorage of the browser is used to store data. Fortunately, Backbone has encapsulated backbone for us. localStorage. js, you only need to reference it.
First, we need to store the model of each user data, so
Var User = Backbone. Model. extend ({defaults: {username: 'default username'}, initialize: function () {if (! This. get ("username") {this. set ({"username": this. defaults. username});} if (! This. get ("userid") {this. set ({"userid": ++ userid });}}});
Ults: some default data. In the initialization function initialize, We just added some simple judgments.
There is a Collection set in Backbone, which is a set of a certain type of model. We will use it here, because we have a list, which is a whole. We use a Collection for unified management, which is more convenient, at the same time, it is also conducive to some things, such as sorting or something. It is OK to directly operate the set. So here we will create one:
Var UserCollection = Backbone. Collection. extend ({model: User, // persistent to local database localStorage: new Store ("users ")});
Model: A Model of a certain type. The default value is Backbone. Model. We set the model to the User created above because it is a collection of users. While localStorage, we can see that its value is a newly created object Store. This Store is the backbone. localStorage. js encapsulated object we have referenced earlier. As for how to work, we will analyze this file in the future. What we know now is to write it like this, we can achieve that our data can correspond to a piece of data whose key is users in localStorage, and can achieve synchronous update.
Well, the model is basically okay. The following is our key View. First, let's figure out how many views are needed. We can see that three views need to be processed, userListView, UserModifyView, and UserView correspond to the list page, add (modify) page, and user details page respectively. Since there is a list, should each list item also have a UserItemView? Here we have added, in fact, this needs to depend on the timing. Well, let's implement them one by one:
For ease of operation, we need a basic View class:
var View = Backbone.View.extend({ register:function (state) { this.state = state; return this; }});
The register function is used to set the state. The state is actually a model.
(1) list item UserItemView
var UserItemView = View.extend({ tagName: 'li', template: _.template($('#user-item-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; }, events:{ 'click .removeUser': 'deleteUser', 'click .viewUser': 'viewUser' }, viewUser: function() { this.state.trigger('viewUser', this.model); }, deleteUser: function () { this.state.trigger('removeUser', this.model); this.remove(); }});
We have seen some parameters. here we need to explain:
TagName: if it is not set, the default value is 'div ', that is, the outer container that holds the view content.
Template: use the template interface provided by underscore to obtain a function (detailed analysis later)
Render: easy to render
Events: events provided by Backbone can be bound by key-value pairs.
The remaining two are corresponding event processing functions.
(2) List UserListView
Var UserListView = View. extend ({template: _.template({('{list-template'}.html (), initialize: function () {var view = this; this. state = new Backbone. model (); this. router = this. options. router; // triggers the reset this when fetch is called. collection. unbind ('reset'); // do not bind this again here. collection. bind ('reset', this. addAll, this); // do not bind setTimeout (function () {view. collection. fetch () ;}, 0) ;}, render: function () {var view = this; this.$el.html (this. template (this. state. toJSON (); this. state. on ('removeuser', function (user) {user. destroy (); // to modify the view of server data. collection. remove (user) ;}); this. state. on ('viewuser', function (user) {view. router. navigate ('user/'+ user. cid, {trigger: true}) ;}); return this ;}, createUserItemView: function (user) {var userItemView = new UserItemView ({model: user }); userid = Math. max. call (null, user. get ('userid'), userid); // make sure that userid will always add userItemView from the maximum. register (this. state ). render (). $ el. appendTo ($ ('# list');}, addAll: function () {this. collection. each (this. createUserItemView. bind (this ));}});
(3) add (modify) UserModifyView
Var UserModifyView = View. extend ({template: _.template((('{modify-template'}.html (), initialize: function () {this. router = this. options. router;}, render: function () {var view = this; if (this. model) {this.$el.html (this. template (this. model. toJSON ();} else {this.w.el.html (this. template ({username: ''});} setTimeout (function () {view. $ el. find ('input '). focus (). select (); // set the focus and select}, 0); return this ;}, events: {'click. add': 'modify'}, modify: function () {var view = this; if (this. model) {this. model. save ({'username': this. $ el. find ('input '). val ()}); // change server data} else {this. router. userCollection. create (new User ({username: view. $ el. find ('input '). val (), userid: + + userid});} this. router. navigate ('LIST', {trigger: true });}});
(4) UserView on the last details page
var UserView = View.extend({ template: _.template($('#user-template').html()), initialize:function () { this.router = this.options.router; }, render: function () { var view = this; this.$el.html(this.template(this.model.toJSON())); return this; }, events:{ 'click .editUser': 'editUser' }, editUser: function() { this.router.navigate('edit/' + this.model.cid, {trigger:true}); this.remove(); }});
We can see that our View contains the Controller's jobs. Therefore, the View contains the roles of View and Controller.
So far, we have just created a bunch of different types. We need something to manage our small examples in a unified manner. We generally choose Application for some processes or things, let's simply call it an App.
At the same time, if we want to see different pictures, it means that the address also changes, or when I click the browser to move forward and backward, we also hope to work well. What should we do? This depends on the role of the Router in Backbone. Of course, he needs the support of history in Backbone.
Let's take a look at our App:
Var App = Backbone. router. extend ({initialize: function (el) {this. el = el; // this. userCollection = new UserCollection ([new User ({username: 'zhang san', userid: ++ userid})]); this. userCollection = new UserCollection () ;}, routes: {'': 'LIST', 'LIST': 'LIST', 'add': 'edit', 'edit /: cid ': 'edit', 'user': 'user', 'user/: cid': 'user'}, list: function () {var router = this; this. clean (); this. currentView = new UserListView ({collection: router. userCollection, router: router }). render (). $ el. appendTo ($ (this. el) ;}, edit: function (cid) {var router = this, user = null; this. clean (); if (cid) {user = router. userCollection. getByCid (cid);} this. currentView = new UserModifyView ({model: user, router: router }). render (). $ el. appendTo ($ (this. el) ;}, user: function (cid) {var router = this, user = null; this. clean (); if (cid) {user = router. userCollection. getByCid (cid);} this. currentView = new UserView ({model: user, router: router }). render (). $ el. appendTo ($ (this. el) ;}, clean: function () {if (this. currentView) {this. currentView. remove (); this. currentView = null ;}}});
Routers: it is also a key-value pair. These rules are used to control the entire process and change history. What are the rules? Here we can briefly understand:
'' |
The hash value is null. |
'LIST '(...) |
Hash: # list |
'Edit/: cid' |
# Editing/111 |
It is easy to understand, but here we only use simple rules, which will be explained in detail when analyzing the Router.
It's still the last step. instantiate our App and everything will be fine.
new App('body');Backbone.history.start();
Do not forget the support of history. You only need to call the start method.
Welcome to the guidance and suggestions.