Backbone.Model exemple
Démonstration d'une écoute sur l'évènement 'change' d'un modèle Backbone. http://www.atinux.fr
by Atinux
HTML
<link rel="stylesheet" href="https://raw.github.com/raphaelgoetter/KNACSS/master/css/knacss.css">
<link rel="stylesheet" href="https://raw.github.com/necolas/css3-github-buttons/master/gh-buttons.css">
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<div id="content">
<div id="search">
Library : <input type="text" name="q" placeholder="jQuery, backbone.js..." class="q" /> <button class="button icon add">Add library</button>
</div>
<div id="edition"></div>
<div id="listing">
<div class="info">Searching...</div>
<div class="libs"></div>
</div>
</div>
<script type="text/template" id="ListingEntryTemplate">
<img src="<%- this.model.get('image') %>" />
<div class="infos">
<b><%- this.model.get('name') %></b>
<a href="<%- this.model.get('website') %>" target="_blank" class="button icon home">Website</a><button class="button icon edit">Edit</button>
</div>
</script>
<script type="text/template" id="EditionTemplate">
<div style="padding: 10px;">
<a class="close">x</a>
Library name:<br/>
<input type="text" value="<%- this.model.get('name') %>" name="name" placeholder="Spine.js, Underscore.js..." /><br/>
Website:<br/>
<input type="text" value="<%- this.model.get('website') %>" name="website" placeholder="https://github.com/mrdoob/three.js/..." /><br/>
Image :<br/>
<input type="text" value="<%- this.model.get('image') %>" name="image" placeholder="http://backbonejs.org/docs/images/backbone.png..." /><br/>
<button class="button icon approve">Save</button> <button class="button icon remove danger">Remove</button>
</div>
</script>
CSS
/*
** Style by Atinux
*/
body {
overflow-y: scroll;
}
#content {
max-width: 800px;
margin: auto;
}
#edition {
background: rgb(227,227,227);
font-size: 1.4em;
line-height: 30px;
position: relative;
overflow: hidden;
height: 0;
}
#edition .button {
margin-top: 10px;
}
#edition .close {
font-size: 1.1em;
font-weight: bold;
position: absolute;
right: 10px;
top: 10px;
background: rgb(220,220,220);
border: 1px solid rgb(210,210,210);
display: inline-block;
padding: 5px;
line-height: 12px;
color: rgb(80,80,80);
cursor: pointer;
}
#edition .close:hover {
background: rgb(210,210,210);
color: rgb(60,60,60);
}
#listing {
font-size: 1.4em;
}
#listing .info {
padding: 10px;
text-align: center;
color: rgb(80,80,80);
}
#listing .libs {
font-size: 1.4em;
/* Prevent vertical gaps */
line-height: 0;
-webkit-column-count: 3;
-webkit-column-gap: 0px;
-moz-column-count: 3;
-moz-column-gap: 0px;
column-count: 3;
column-gap: 0px;
}
#listing .libs > div {
margin: 5px;
position: relative;
border: 2px rgb(200,200,200) solid;
}
#listing .libs > div .infos {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
text-align: center;
height: 40px;
font-size: 1.2em;
opacity: 0;
-webkit-transition: all 0.2s ease;
-moz-transition: all 0.2s ease;
-o-transition: all 0.2s ease;
transition: all 0.2s ease;
}
#listing .libs > div .infos b {
font-size: 0.7em;
display: block;
margin-bottom: 15px;
}
#listing .libs img {
width: 100% !important;
height: auto !important;
min-height: 70px;
background: rgb(230,230,230);
-webkit-transition: all 0.2s ease;
-moz-transition: all 0.2s ease;
-o-transition: all 0.2s ease;
transition: all 0.2s ease;
}
#listing .libs > div:hover {
border: 2px rgb(220,220,220) solid;
}
#listing .libs > div:hover img {
opacity: 0.1;
}
#listing .libs > div:hover .infos {
opacity: 1;
}
#search {
...
JavaScript
// Namespace
window.app = {
API: 'http://api-as-a-service.jit.su/api',
Views: {},
Models: {},
e: _.extend({}, Backbone.Events),
callAPI: function (params) {
var url = (typeof(params) === 'string' ? params : params.url),
data = params.data || {},
type = params.type || params.method || 'GET';
if (type === 'GET') {
data = $.param(data);
return $.getJSON(url, data);
}
data = JSON.stringify(data);
return $.ajax({
url: url,
contentType: 'application/json',
dataType: 'json',
data: data,
type: type
});
},
init: function () {
// Init views
// ** search
new app.Views.Search();
// ** listing
new app.Views.Listing();
// ** edition
new app.Views.Edition();
}
};
// Model
app.Models.Library = Backbone.Model.extend({
defaults: {
name: 'Library name missing',
website: 'http://www.atinux.fr',
image: 'https://encrypted-tbn0.google.com/images?q=tbn:ANd9GcReILs3s72cLDuX2EqaIiIM_3KtUW9rtDKJujLJhvEHeKerHw3x'
}
});
// Views
// ** Search
app.Views.Search = Backbone.View.extend({
initialize: function () {
this.search();
},
el: '#search',
events: {
'keyup input': 'search',
'click .add': 'addLibrary'
},
search: function (e) {
var params = {};
params.q = this.$('.q').val();
// Trigger a "search" event
app.e.trigger('search', params);
// call API to get matching results
app.callAPI({
url: app.API + '/libraries',
data: params
})
.success(function (res) {
app.e.trigger('searchResults', null, res);
})
.error(function (err) {
app.e.trigger('searchResults', err);
});
},
addLibrary: function (e) {
app.e.trigger('add');
}
});
// ** Listing
app.Views.Listing = Backbone.View.extend({
el: '#listing',
initialize: function () {
_.bindAll(this);
this.$info = this.$('.info');
this.$libs = this.$('.libs');
app.e.on('search',...