XBMCMM Ember.js Intro (Handlebars)
by gugahoi
HTML
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script>
<script src="https://raw.github.com/emberjs/ember.js/release-builds/ember-1.0.0-pre.4.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.0/bootstrap.min.js"></script>
<script src="http://www.thetravellingbarman.com.au/scripts/ember-data.js"></script>
<script type="text/x-handlebars" data-template-name="application">
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<a class="brand" href="#">XBMCMM</a>
<ul class="nav">
<li><a href="#">Home</a></li>
{{#linkTo "movies" tagName="li"}}<a href="#">Movies</a>{{/linkTo}}
{{#linkTo "tv" tagName="li"}}<a href="#">TV</a>{{/linkTo}}
</ul>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
{{ outlet }}
</div>
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="movies">
<div class="row-fluid">
<div class="span3" id="moviesSidebar">
{{ partial "movieMenu" }}
</div>
<div class="span9" id="moviesContent">
<div class="well">
{{ outlet }}
</div>
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="movies/index">
<h2>Select a movie on the sidebar</h2>
</script>
<script type="text/x-handlebars" data-template-name="_movieMenu">
{{view Em.TextField valueBinding="filter" class="span12" placeholder="Filter"}}
<ul class="unstyled well">
{{#each movie in filteredMovies}}
<li>
{{#linkTo "movie" movie}}
{{ movie.name }}
{{/linkTo}}
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars"...
CSS
@import url('http://twitter.github.com/bootstrap/assets/css/bootstrap.css');
body {
margin-top: 60px;
}
.navbar .brand {
margin-left: 0;
}
#moviesSidebar ul li {
padding: 10px;
line-height: 20px;
height: 20px;
}
#moviesSidebar ul li:hover, #moviesSidebar ul li.active {
background-color: #0051ff;
color: white;
cursor: pointer;
}
.hidden {
display: none;
}
JavaScript
/*global App*/
'use strict';
window.App = Ember.Application.create();
// Router
App.Router.map(function() {
this.resource('movies', function() {
this.resource('movie', { path: ':movie_id' });
});
this.resource('tv');
});
App.MoviesRoute = Ember.Route.extend({
model: function() {
return App.Movies.find();
}
});
App.MovieRoute = Ember.Route.extend({
model: function() {
return App.Movie.find();
}
});
// Controllers
// Implement explicitly to use the object proxy.
App.MoviesController = Ember.ArrayController.extend({
filter: '',
sortProperties: ['name'],
filteredMovies: function() {
var filter = this.get('filter').toLowerCase();
var content = this.get('content');
if(!filter) { return content; }
return content.filter(function(item, idx) {
return item.get('name').toLowerCase().indexOf(filter) !== -1;
}, this);
}.property('content', 'filter')
});
// Models
App.Store = DS.Store.extend({
revision: 11,
adapter: 'DS.FixtureAdapter'
});
App.Movies = DS.Model.extend({
movieList: DS.hasMany('App.Movie')
});
App.Movie = DS.Model.extend({
movie: DS.belongsTo('App.Movies')
});
App.Movies = DS.Model.extend({
name: DS.attr('string'),
isHidden: DS.attr('boolean')
});
App.Movie = DS.Model.extend({
name: DS.attr('string'),
imageUrl: DS.attr('string'),
rating: DS.attr('number'),
});
App.Movies.FIXTURES = [{
id: 1,
name: 'Batman Begins',
isHidden: false
}, {
id: 2,
name: 'Spiderman',
isHidden: false
}, {
id: 3,
name: 'Superman',
isHidden: false
}, {
id: 4,
name: 'Aquaman',
isHidden: false
}, {
id: 5,
name: 'Green Lantern',
isHidden: false
}];
App.Movie.FIXTURES = [{
id: 1,
name: 'Batman Begins',
imageUrl: 'img/pizza.png',
rating: 10
}, {
id: 2,
name: 'Spiderman',
imageUrl: 'img/pancakes.png',
rating: 10
}, {
id: 3,
name: 'Superman',
imageUrl: 'img/fries.png',
rating: 10
}, {
id: 4,
name: 'Aquaman',
imageUrl: 'img/hotdog.png',
...