Created
July 6, 2017 13:08
-
-
Save shafi-shaikat/4e3b3a89958915d67232d7e9fb5d5e14 to your computer and use it in GitHub Desktop.
Ember Starter Kit // source http://jsbin.com/rubikihiqa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Ember Starter Kit</title> | |
| <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css"> | |
| <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> | |
| <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> | |
| <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> | |
| <script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script> | |
| <script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"></script> | |
| <script src="http://builds.emberjs.com.s3.amazonaws.com/beta/daily/20140219/ember-data.js"></script> | |
| <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> | |
| <style> | |
| img { | |
| max-width: 100%; | |
| } | |
| </style> | |
| <style id="jsbin-css"> | |
| /* Put your CSS here */ | |
| html, body { | |
| } | |
| html, body, #wrapper { | |
| width: 100%; | |
| height: 100%; | |
| overflow: hidden; | |
| } | |
| #wrapper > h2 { | |
| margin-left: 10px; | |
| } | |
| #sidebar { | |
| width: 10%; | |
| min-width: 180px; | |
| float: left; | |
| height: 10000px; | |
| padding: 20px; | |
| } | |
| #sidebar h4 { | |
| color: #aaa; | |
| font-weight: normal; | |
| font-size: 13px; | |
| text-transform: uppercase; | |
| letter-spacing: .05em; | |
| margin-top: 0; | |
| } | |
| #sidebar ul { | |
| list-style: none; | |
| margin: 0 0 20px; | |
| padding:0; | |
| } | |
| #main { | |
| width: 80%; | |
| padding: 20px; | |
| float: left; | |
| } | |
| h3.top-title { | |
| margin-top: 0; | |
| } | |
| .albums { | |
| margin-top: 20px; | |
| } | |
| .album { | |
| display: inline-block; | |
| margin: 0 30px 30px 0; | |
| width: 15%; | |
| color: #333; | |
| } | |
| .album:hover { | |
| text-decoration: none; | |
| } | |
| .album img { | |
| box-shadow: 0 0 1px #ddd; | |
| display: inline-block; | |
| margin-bottom: 8px; | |
| } | |
| #left-side { | |
| width: 33%; | |
| } | |
| #left-side img { | |
| box-shadow: 0 0 1px #ddd; | |
| display: inline-block; | |
| } | |
| #right-side { | |
| width: 63%; | |
| } | |
| #tracklist { | |
| min-height: 220px; | |
| } | |
| .loader { | |
| text-align: center; | |
| font-size: 1.5em; | |
| margin-top: 20px; | |
| } | |
| .section { | |
| border-top: 1px solid #eee; | |
| margin-top: 40px; | |
| text-align: center; | |
| } | |
| .section h3 { | |
| display: inline-block; | |
| background: white; | |
| padding: 0 10px; | |
| margin-bottom: 20px; | |
| color: #aaa; | |
| font-weight: normal; | |
| font-size: 13px; | |
| text-transform: uppercase; | |
| letter-spacing: .05em; | |
| margin: 0; | |
| position: relative; | |
| top: -10px; | |
| } | |
| ul.activities { | |
| text-align: left; | |
| margin-top: 20px; | |
| } | |
| ul.activities li { | |
| display: inline-block; | |
| width: 25%; | |
| text-align: center; | |
| } | |
| ul.reviews { | |
| list-style: none; | |
| text-align:left; | |
| margin-top: 20px; | |
| } | |
| ul.reviews li { | |
| width: 80%; | |
| margin-bottom: 20px; | |
| } | |
| .reviews li { | |
| clear: left; | |
| } | |
| .reviews img { | |
| float: left; | |
| margin: 0 20px 20px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <script type="text/x-handlebars"> | |
| <div id="wrapper"> | |
| <h2>Rdio Clone</h2> | |
| <div id="sidebar"> | |
| <h4>playlists</h4> | |
| <ul> | |
| <li> | |
| Cool Playlist | |
| </li> | |
| </ul> | |
| </div> | |
| <div id="main"> | |
| {{outlet}} | |
| </div> | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="index"> | |
| <h3 class="top-title">Cool Playlist</h3> | |
| <div class="albums"> | |
| {{#each album in model}} | |
| {{#link-to 'album' album class="album"}} | |
| <img {{bind-attr src=album.image}} /> | |
| {{album.title}} | |
| {{/link-to}} | |
| {{/each}} | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="album"> | |
| <div id="album"> | |
| {{partial 'player'}} | |
| {{partial 'albuminfo'}} | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="_player"> | |
| <div id="left-side" class="pull-left"> | |
| <img {{bind-attr src=image}} /> | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="_albuminfo"> | |
| <div id="right-side" class="pull-right"> | |
| <h4>{{title}}</h4> | |
| <div id="tracklist"> | |
| tracklist... | |
| </div> | |
| <div id="activities" class="section"> | |
| <h3>Activity</h3> | |
| <div>{{#link-to 'activities'}}Load Activity{{/link-to}}</div> | |
| {{outlet activities}} | |
| </div> | |
| <div id="reviews" class="section"> | |
| <h3>Reviews</h3> | |
| <!-- <div>{{#link-to 'reviews'}}Load Reviews{{/link-to}}</div> --> | |
| <!-- <div><a href="#" {{action 'loadReviews' model}}>Load Reviews</a></div> --> | |
| <div><a href="#" {{action 'loadMoreReviews' model}}>Load Reviews</a></div> | |
| {{render 'reviews/index'}} | |
| {{outlet reviews}} | |
| </div> | |
| {{! dont do this since render doesnt fire the loading transitions}} | |
| {{!render 'activities/index' activities}} | |
| {{! render 'reviews/index'}} | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="loading"> | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching data...</p> | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="album/loading"> | |
| <div class="loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching album data...</p> | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="activities/loading"> | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching activity data...</p> | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="reviews/loading"> | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching review data...</p> | |
| </div> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="activities"> | |
| {{outlet}} | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="activities/index"> | |
| <ul class="activities"> | |
| {{#each}} | |
| <li> | |
| <img src="http://api.randomuser.me/portraits/thumb/lego/6.jpg" /> | |
| <p>{{name}}</p> | |
| </li> | |
| {{/each}} | |
| </ul> | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="reviews"> | |
| {{outlet}} | |
| </script> | |
| <script type="text/x-handlebars" data-template-name="reviews/index"> | |
| {{#if isPending}} | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching review data...</p> | |
| </div> | |
| {{else}} | |
| <ul class="reviews"> | |
| {{#each}} | |
| <li><img src="http://api.randomuser.me/portraits/thumb/lego/8.jpg" />{{body}}</li> | |
| {{/each}} | |
| </ul> | |
| {{/if}} | |
| </script> | |
| <script id="jsbin-javascript"> | |
| App = Ember.Application.create(); | |
| App.ApplicationAdapter = DS.FixtureAdapter; | |
| App.ApplicationAdapter.reopen({ | |
| latency: 2000 | |
| }); | |
| // router | |
| App.Router.map(function() { | |
| this.resource('album', { path: '/albums/:album_id'}, function() { | |
| this.resource('activities', function() {}); | |
| this.resource('reviews', function() {}); | |
| }); | |
| }); | |
| //////////// | |
| // mixins | |
| App.SlowAlbumAssociationLoader = Ember.Mixin.create({ | |
| loadAssociation: function(album, relationshipString) { | |
| // Wrap this in a promise / later even though we're using | |
| // fixture latency. Otherwise, it wont simulate delay when | |
| // loading links. | |
| return new Ember.RSVP.Promise(function(resolve, reject) { | |
| Ember.run.later(function() { | |
| resolve(album.get(relationshipString)); | |
| }, 1000); | |
| }); | |
| } | |
| }); | |
| //////////// | |
| // routes | |
| App.ApplicationRoute = Ember.Route.extend({ | |
| actions: { | |
| loading: function() { | |
| console.log('application loading man!'); | |
| return true; | |
| } | |
| } | |
| }); | |
| App.IndexRoute = Ember.Route.extend({ | |
| model: function() { | |
| return this.store.find('album'); | |
| } | |
| }); | |
| App.AlbumRoute = Ember.Route.extend({ | |
| model: function(params) { | |
| return this.store.find('album', params.album_id); | |
| }, | |
| actions: { | |
| loadMoreReviews: function(album) { | |
| var reviewsController = this.controllerFor('reviews.index'); | |
| reviewsController.set('promise', album.get('reviews')); | |
| }, | |
| loadReviews: function(album) { | |
| this.render('reviews/loading', { into: 'album', outlet: 'reviews' }); | |
| var _this = this; | |
| album.get('reviews').then(function(reviews){ | |
| _this.render('reviews/index', { | |
| into: 'album', | |
| outlet: 'reviews', | |
| model: reviews | |
| }); | |
| }); | |
| } | |
| } | |
| }); | |
| App.AlbumLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function(controller) { | |
| this.render({ outlet: this._outletFromURL() }); | |
| }, | |
| _outletFromURL: function() { | |
| var outlet = this.get('router.router.activeTransition.targetName') || 'activities'; | |
| return outlet.replace(/\.\w+/, ''); | |
| } | |
| }); | |
| App.ActivitiesIndexRoute = Ember.Route.extend(App.SlowAlbumAssociationLoader, { | |
| model: function() { | |
| var album = this.modelFor('album'); | |
| return this.loadAssociation(album, 'activities'); | |
| }, | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities'}); | |
| } | |
| }); | |
| App.ActivitiesRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities' }); | |
| } | |
| }); | |
| App.ActivitiesLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities'}); | |
| } | |
| }); | |
| App.ReviewsRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews'}); | |
| } | |
| }); | |
| App.ReviewsLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews' }); | |
| } | |
| }); | |
| App.ReviewsIndexRoute = Ember.Route.extend(App.SlowAlbumAssociationLoader, { | |
| model: function() { | |
| var album = this.modelFor('album'); | |
| return this.loadAssociation(album, 'reviews'); | |
| }, | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews'}); | |
| }, | |
| }); | |
| /////////// | |
| // controllers | |
| App.ReviewsIndexController = Ember.ArrayController.extend(Ember.PromiseProxyMixin, { | |
| setupPromise: function() { | |
| this.set('promise', new Ember.RSVP.all([])); | |
| }.on('init') | |
| }); | |
| /////////// | |
| // models | |
| App.Album = DS.Model.extend({ | |
| title: DS.attr(), | |
| image: DS.attr(), | |
| reviews: DS.hasMany('review', { async: true }), | |
| activities: DS.hasMany('activity', { async: true }) | |
| }); | |
| App.Album.FIXTURES = [ | |
| { id: 1, title: 'Addicted!', image: 'http://www.metal-archives.com/images/2/4/9/7/249789.jpg', reviews: [1,2], activities: [1,2]}, | |
| { id: 2, title: 'Wasting Light', image: 'http://upload.wikimedia.org/wikipedia/en/0/05/Foo_Fighters_Wasting_Light_Album_Cover.jpg'} | |
| ]; | |
| App.Review = DS.Model.extend({ | |
| body: DS.attr(), | |
| album: DS.belongsTo('album') | |
| }); | |
| App.Review.FIXTURES = [ | |
| { id: 1, body: "cool."}, | |
| { id: 2, body: "this album is mo betta than the last."} | |
| ]; | |
| App.Activity = DS.Model.extend({ | |
| name: DS.attr(), | |
| album: DS.belongsTo('album') | |
| }); | |
| App.Activity.FIXTURES = [ | |
| { id: 1, name: "dude listened"}, | |
| { id: 2, name: "dave shared"} | |
| ]; | |
| </script> | |
| <script id="jsbin-source-html" type="text/html"><!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Ember Starter Kit</title> | |
| <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css"> | |
| <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> | |
| <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> | |
| <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"><\/script> | |
| <script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"><\/script> | |
| <script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"><\/script> | |
| <script src="http://builds.emberjs.com.s3.amazonaws.com/beta/daily/20140219/ember-data.js"><\/script> | |
| <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"><\/script> | |
| <style> | |
| img { | |
| max-width: 100%; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <script type="text/x-handlebars"> | |
| <div id="wrapper"> | |
| <h2>Rdio Clone</h2> | |
| <div id="sidebar"> | |
| <h4>playlists</h4> | |
| <ul> | |
| <li> | |
| Cool Playlist | |
| </li> | |
| </ul> | |
| </div> | |
| <div id="main"> | |
| {{outlet}} | |
| </div> | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="index"> | |
| <h3 class="top-title">Cool Playlist</h3> | |
| <div class="albums"> | |
| {{#each album in model}} | |
| {{#link-to 'album' album class="album"}} | |
| <img {{bind-attr src=album.image}} /> | |
| {{album.title}} | |
| {{/link-to}} | |
| {{/each}} | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="album"> | |
| <div id="album"> | |
| {{partial 'player'}} | |
| {{partial 'albuminfo'}} | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="_player"> | |
| <div id="left-side" class="pull-left"> | |
| <img {{bind-attr src=image}} /> | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="_albuminfo"> | |
| <div id="right-side" class="pull-right"> | |
| <h4>{{title}}</h4> | |
| <div id="tracklist"> | |
| tracklist... | |
| </div> | |
| <div id="activities" class="section"> | |
| <h3>Activity</h3> | |
| <div>{{#link-to 'activities'}}Load Activity{{/link-to}}</div> | |
| {{outlet activities}} | |
| </div> | |
| <div id="reviews" class="section"> | |
| <h3>Reviews</h3> | |
| <\!-- <div>{{#link-to 'reviews'}}Load Reviews{{/link-to}}</div> --> | |
| <\!-- <div><a href="#" {{action 'loadReviews' model}}>Load Reviews</a></div> --> | |
| <div><a href="#" {{action 'loadMoreReviews' model}}>Load Reviews</a></div> | |
| {{render 'reviews/index'}} | |
| {{outlet reviews}} | |
| </div> | |
| {{! dont do this since render doesnt fire the loading transitions}} | |
| {{!render 'activities/index' activities}} | |
| {{! render 'reviews/index'}} | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="loading"> | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching data...</p> | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="album/loading"> | |
| <div class="loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching album data...</p> | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="activities/loading"> | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching activity data...</p> | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="reviews/loading"> | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching review data...</p> | |
| </div> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="activities"> | |
| {{outlet}} | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="activities/index"> | |
| <ul class="activities"> | |
| {{#each}} | |
| <li> | |
| <img src="http://api.randomuser.me/portraits/thumb/lego/6.jpg" /> | |
| <p>{{name}}</p> | |
| </li> | |
| {{/each}} | |
| </ul> | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="reviews"> | |
| {{outlet}} | |
| <\/script> | |
| <script type="text/x-handlebars" data-template-name="reviews/index"> | |
| {{#if isPending}} | |
| <div class="album-loader loader"> | |
| <i class="fa fa-cog fa-spin"></i> | |
| <p>Fetching review data...</p> | |
| </div> | |
| {{else}} | |
| <ul class="reviews"> | |
| {{#each}} | |
| <li><img src="http://api.randomuser.me/portraits/thumb/lego/8.jpg" />{{body}}</li> | |
| {{/each}} | |
| </ul> | |
| {{/if}} | |
| <\/script> | |
| </body> | |
| </html> | |
| </script> | |
| <script id="jsbin-source-css" type="text/css">/* Put your CSS here */ | |
| html, body { | |
| } | |
| html, body, #wrapper { | |
| width: 100%; | |
| height: 100%; | |
| overflow: hidden; | |
| } | |
| #wrapper > h2 { | |
| margin-left: 10px; | |
| } | |
| #sidebar { | |
| width: 10%; | |
| min-width: 180px; | |
| float: left; | |
| height: 10000px; | |
| padding: 20px; | |
| } | |
| #sidebar h4 { | |
| color: #aaa; | |
| font-weight: normal; | |
| font-size: 13px; | |
| text-transform: uppercase; | |
| letter-spacing: .05em; | |
| margin-top: 0; | |
| } | |
| #sidebar ul { | |
| list-style: none; | |
| margin: 0 0 20px; | |
| padding:0; | |
| } | |
| #main { | |
| width: 80%; | |
| padding: 20px; | |
| float: left; | |
| } | |
| h3.top-title { | |
| margin-top: 0; | |
| } | |
| .albums { | |
| margin-top: 20px; | |
| } | |
| .album { | |
| display: inline-block; | |
| margin: 0 30px 30px 0; | |
| width: 15%; | |
| color: #333; | |
| } | |
| .album:hover { | |
| text-decoration: none; | |
| } | |
| .album img { | |
| box-shadow: 0 0 1px #ddd; | |
| display: inline-block; | |
| margin-bottom: 8px; | |
| } | |
| #left-side { | |
| width: 33%; | |
| } | |
| #left-side img { | |
| box-shadow: 0 0 1px #ddd; | |
| display: inline-block; | |
| } | |
| #right-side { | |
| width: 63%; | |
| } | |
| #tracklist { | |
| min-height: 220px; | |
| } | |
| .loader { | |
| text-align: center; | |
| font-size: 1.5em; | |
| margin-top: 20px; | |
| } | |
| .section { | |
| border-top: 1px solid #eee; | |
| margin-top: 40px; | |
| text-align: center; | |
| } | |
| .section h3 { | |
| display: inline-block; | |
| background: white; | |
| padding: 0 10px; | |
| margin-bottom: 20px; | |
| color: #aaa; | |
| font-weight: normal; | |
| font-size: 13px; | |
| text-transform: uppercase; | |
| letter-spacing: .05em; | |
| margin: 0; | |
| position: relative; | |
| top: -10px; | |
| } | |
| ul.activities { | |
| text-align: left; | |
| margin-top: 20px; | |
| } | |
| ul.activities li { | |
| display: inline-block; | |
| width: 25%; | |
| text-align: center; | |
| } | |
| ul.reviews { | |
| list-style: none; | |
| text-align:left; | |
| margin-top: 20px; | |
| } | |
| ul.reviews li { | |
| width: 80%; | |
| margin-bottom: 20px; | |
| } | |
| .reviews li { | |
| clear: left; | |
| } | |
| .reviews img { | |
| float: left; | |
| margin: 0 20px 20px; | |
| }</script> | |
| <script id="jsbin-source-javascript" type="text/javascript">App = Ember.Application.create(); | |
| App.ApplicationAdapter = DS.FixtureAdapter; | |
| App.ApplicationAdapter.reopen({ | |
| latency: 2000 | |
| }); | |
| // router | |
| App.Router.map(function() { | |
| this.resource('album', { path: '/albums/:album_id'}, function() { | |
| this.resource('activities', function() {}); | |
| this.resource('reviews', function() {}); | |
| }); | |
| }); | |
| //////////// | |
| // mixins | |
| App.SlowAlbumAssociationLoader = Ember.Mixin.create({ | |
| loadAssociation: function(album, relationshipString) { | |
| // Wrap this in a promise / later even though we're using | |
| // fixture latency. Otherwise, it wont simulate delay when | |
| // loading links. | |
| return new Ember.RSVP.Promise(function(resolve, reject) { | |
| Ember.run.later(function() { | |
| resolve(album.get(relationshipString)); | |
| }, 1000); | |
| }); | |
| } | |
| }); | |
| //////////// | |
| // routes | |
| App.ApplicationRoute = Ember.Route.extend({ | |
| actions: { | |
| loading: function() { | |
| console.log('application loading man!'); | |
| return true; | |
| } | |
| } | |
| }); | |
| App.IndexRoute = Ember.Route.extend({ | |
| model: function() { | |
| return this.store.find('album'); | |
| } | |
| }); | |
| App.AlbumRoute = Ember.Route.extend({ | |
| model: function(params) { | |
| return this.store.find('album', params.album_id); | |
| }, | |
| actions: { | |
| loadMoreReviews: function(album) { | |
| var reviewsController = this.controllerFor('reviews.index'); | |
| reviewsController.set('promise', album.get('reviews')); | |
| }, | |
| loadReviews: function(album) { | |
| this.render('reviews/loading', { into: 'album', outlet: 'reviews' }); | |
| var _this = this; | |
| album.get('reviews').then(function(reviews){ | |
| _this.render('reviews/index', { | |
| into: 'album', | |
| outlet: 'reviews', | |
| model: reviews | |
| }); | |
| }); | |
| } | |
| } | |
| }); | |
| App.AlbumLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function(controller) { | |
| this.render({ outlet: this._outletFromURL() }); | |
| }, | |
| _outletFromURL: function() { | |
| var outlet = this.get('router.router.activeTransition.targetName') || 'activities'; | |
| return outlet.replace(/\.\w+/, ''); | |
| } | |
| }); | |
| App.ActivitiesIndexRoute = Ember.Route.extend(App.SlowAlbumAssociationLoader, { | |
| model: function() { | |
| var album = this.modelFor('album'); | |
| return this.loadAssociation(album, 'activities'); | |
| }, | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities'}); | |
| } | |
| }); | |
| App.ActivitiesRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities' }); | |
| } | |
| }); | |
| App.ActivitiesLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities'}); | |
| } | |
| }); | |
| App.ReviewsRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews'}); | |
| } | |
| }); | |
| App.ReviewsLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews' }); | |
| } | |
| }); | |
| App.ReviewsIndexRoute = Ember.Route.extend(App.SlowAlbumAssociationLoader, { | |
| model: function() { | |
| var album = this.modelFor('album'); | |
| return this.loadAssociation(album, 'reviews'); | |
| }, | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews'}); | |
| }, | |
| }); | |
| /////////// | |
| // controllers | |
| App.ReviewsIndexController = Ember.ArrayController.extend(Ember.PromiseProxyMixin, { | |
| setupPromise: function() { | |
| this.set('promise', new Ember.RSVP.all([])); | |
| }.on('init') | |
| }); | |
| /////////// | |
| // models | |
| App.Album = DS.Model.extend({ | |
| title: DS.attr(), | |
| image: DS.attr(), | |
| reviews: DS.hasMany('review', { async: true }), | |
| activities: DS.hasMany('activity', { async: true }) | |
| }); | |
| App.Album.FIXTURES = [ | |
| { id: 1, title: 'Addicted!', image: 'http://www.metal-archives.com/images/2/4/9/7/249789.jpg', reviews: [1,2], activities: [1,2]}, | |
| { id: 2, title: 'Wasting Light', image: 'http://upload.wikimedia.org/wikipedia/en/0/05/Foo_Fighters_Wasting_Light_Album_Cover.jpg'} | |
| ]; | |
| App.Review = DS.Model.extend({ | |
| body: DS.attr(), | |
| album: DS.belongsTo('album') | |
| }); | |
| App.Review.FIXTURES = [ | |
| { id: 1, body: "cool."}, | |
| { id: 2, body: "this album is mo betta than the last."} | |
| ]; | |
| App.Activity = DS.Model.extend({ | |
| name: DS.attr(), | |
| album: DS.belongsTo('album') | |
| }); | |
| App.Activity.FIXTURES = [ | |
| { id: 1, name: "dude listened"}, | |
| { id: 2, name: "dave shared"} | |
| ];</script></body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Put your CSS here */ | |
| html, body { | |
| } | |
| html, body, #wrapper { | |
| width: 100%; | |
| height: 100%; | |
| overflow: hidden; | |
| } | |
| #wrapper > h2 { | |
| margin-left: 10px; | |
| } | |
| #sidebar { | |
| width: 10%; | |
| min-width: 180px; | |
| float: left; | |
| height: 10000px; | |
| padding: 20px; | |
| } | |
| #sidebar h4 { | |
| color: #aaa; | |
| font-weight: normal; | |
| font-size: 13px; | |
| text-transform: uppercase; | |
| letter-spacing: .05em; | |
| margin-top: 0; | |
| } | |
| #sidebar ul { | |
| list-style: none; | |
| margin: 0 0 20px; | |
| padding:0; | |
| } | |
| #main { | |
| width: 80%; | |
| padding: 20px; | |
| float: left; | |
| } | |
| h3.top-title { | |
| margin-top: 0; | |
| } | |
| .albums { | |
| margin-top: 20px; | |
| } | |
| .album { | |
| display: inline-block; | |
| margin: 0 30px 30px 0; | |
| width: 15%; | |
| color: #333; | |
| } | |
| .album:hover { | |
| text-decoration: none; | |
| } | |
| .album img { | |
| box-shadow: 0 0 1px #ddd; | |
| display: inline-block; | |
| margin-bottom: 8px; | |
| } | |
| #left-side { | |
| width: 33%; | |
| } | |
| #left-side img { | |
| box-shadow: 0 0 1px #ddd; | |
| display: inline-block; | |
| } | |
| #right-side { | |
| width: 63%; | |
| } | |
| #tracklist { | |
| min-height: 220px; | |
| } | |
| .loader { | |
| text-align: center; | |
| font-size: 1.5em; | |
| margin-top: 20px; | |
| } | |
| .section { | |
| border-top: 1px solid #eee; | |
| margin-top: 40px; | |
| text-align: center; | |
| } | |
| .section h3 { | |
| display: inline-block; | |
| background: white; | |
| padding: 0 10px; | |
| margin-bottom: 20px; | |
| color: #aaa; | |
| font-weight: normal; | |
| font-size: 13px; | |
| text-transform: uppercase; | |
| letter-spacing: .05em; | |
| margin: 0; | |
| position: relative; | |
| top: -10px; | |
| } | |
| ul.activities { | |
| text-align: left; | |
| margin-top: 20px; | |
| } | |
| ul.activities li { | |
| display: inline-block; | |
| width: 25%; | |
| text-align: center; | |
| } | |
| ul.reviews { | |
| list-style: none; | |
| text-align:left; | |
| margin-top: 20px; | |
| } | |
| ul.reviews li { | |
| width: 80%; | |
| margin-bottom: 20px; | |
| } | |
| .reviews li { | |
| clear: left; | |
| } | |
| .reviews img { | |
| float: left; | |
| margin: 0 20px 20px; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| App = Ember.Application.create(); | |
| App.ApplicationAdapter = DS.FixtureAdapter; | |
| App.ApplicationAdapter.reopen({ | |
| latency: 2000 | |
| }); | |
| // router | |
| App.Router.map(function() { | |
| this.resource('album', { path: '/albums/:album_id'}, function() { | |
| this.resource('activities', function() {}); | |
| this.resource('reviews', function() {}); | |
| }); | |
| }); | |
| //////////// | |
| // mixins | |
| App.SlowAlbumAssociationLoader = Ember.Mixin.create({ | |
| loadAssociation: function(album, relationshipString) { | |
| // Wrap this in a promise / later even though we're using | |
| // fixture latency. Otherwise, it wont simulate delay when | |
| // loading links. | |
| return new Ember.RSVP.Promise(function(resolve, reject) { | |
| Ember.run.later(function() { | |
| resolve(album.get(relationshipString)); | |
| }, 1000); | |
| }); | |
| } | |
| }); | |
| //////////// | |
| // routes | |
| App.ApplicationRoute = Ember.Route.extend({ | |
| actions: { | |
| loading: function() { | |
| console.log('application loading man!'); | |
| return true; | |
| } | |
| } | |
| }); | |
| App.IndexRoute = Ember.Route.extend({ | |
| model: function() { | |
| return this.store.find('album'); | |
| } | |
| }); | |
| App.AlbumRoute = Ember.Route.extend({ | |
| model: function(params) { | |
| return this.store.find('album', params.album_id); | |
| }, | |
| actions: { | |
| loadMoreReviews: function(album) { | |
| var reviewsController = this.controllerFor('reviews.index'); | |
| reviewsController.set('promise', album.get('reviews')); | |
| }, | |
| loadReviews: function(album) { | |
| this.render('reviews/loading', { into: 'album', outlet: 'reviews' }); | |
| var _this = this; | |
| album.get('reviews').then(function(reviews){ | |
| _this.render('reviews/index', { | |
| into: 'album', | |
| outlet: 'reviews', | |
| model: reviews | |
| }); | |
| }); | |
| } | |
| } | |
| }); | |
| App.AlbumLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function(controller) { | |
| this.render({ outlet: this._outletFromURL() }); | |
| }, | |
| _outletFromURL: function() { | |
| var outlet = this.get('router.router.activeTransition.targetName') || 'activities'; | |
| return outlet.replace(/\.\w+/, ''); | |
| } | |
| }); | |
| App.ActivitiesIndexRoute = Ember.Route.extend(App.SlowAlbumAssociationLoader, { | |
| model: function() { | |
| var album = this.modelFor('album'); | |
| return this.loadAssociation(album, 'activities'); | |
| }, | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities'}); | |
| } | |
| }); | |
| App.ActivitiesRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities' }); | |
| } | |
| }); | |
| App.ActivitiesLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'activities'}); | |
| } | |
| }); | |
| App.ReviewsRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews'}); | |
| } | |
| }); | |
| App.ReviewsLoadingRoute = Ember.Route.extend({ | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews' }); | |
| } | |
| }); | |
| App.ReviewsIndexRoute = Ember.Route.extend(App.SlowAlbumAssociationLoader, { | |
| model: function() { | |
| var album = this.modelFor('album'); | |
| return this.loadAssociation(album, 'reviews'); | |
| }, | |
| renderTemplate: function() { | |
| this.render({ outlet: 'reviews'}); | |
| }, | |
| }); | |
| /////////// | |
| // controllers | |
| App.ReviewsIndexController = Ember.ArrayController.extend(Ember.PromiseProxyMixin, { | |
| setupPromise: function() { | |
| this.set('promise', new Ember.RSVP.all([])); | |
| }.on('init') | |
| }); | |
| /////////// | |
| // models | |
| App.Album = DS.Model.extend({ | |
| title: DS.attr(), | |
| image: DS.attr(), | |
| reviews: DS.hasMany('review', { async: true }), | |
| activities: DS.hasMany('activity', { async: true }) | |
| }); | |
| App.Album.FIXTURES = [ | |
| { id: 1, title: 'Addicted!', image: 'http://www.metal-archives.com/images/2/4/9/7/249789.jpg', reviews: [1,2], activities: [1,2]}, | |
| { id: 2, title: 'Wasting Light', image: 'http://upload.wikimedia.org/wikipedia/en/0/05/Foo_Fighters_Wasting_Light_Album_Cover.jpg'} | |
| ]; | |
| App.Review = DS.Model.extend({ | |
| body: DS.attr(), | |
| album: DS.belongsTo('album') | |
| }); | |
| App.Review.FIXTURES = [ | |
| { id: 1, body: "cool."}, | |
| { id: 2, body: "this album is mo betta than the last."} | |
| ]; | |
| App.Activity = DS.Model.extend({ | |
| name: DS.attr(), | |
| album: DS.belongsTo('album') | |
| }); | |
| App.Activity.FIXTURES = [ | |
| { id: 1, name: "dude listened"}, | |
| { id: 2, name: "dave shared"} | |
| ]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment