Ember Latest

The latest build of Ember.

HTML

<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.2.1.js"></script>
<script src="http://builds.emberjs.com/tags/v1.4.0/ember.js"></script>
<script type="text/x-handlebars" data-template-name="application">
    <h1>Complete vs Progressive Model Loading</h1>
    
    {{link-to 'Complete' 'slow'}}
    {{link-to 'Progressive' 'fast'}}
    {{link-to 'Reset' 'index'}}
    
    {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="sample">
  <br/>
  <h2>Developer Profiles</h2>
  <table>
      <thead><th>First Name</th><th>Last Name</th></thead>
      <tbody>
          {{#each content}}
          <tr><td>{{firstName}}</td><td>{{lastName}}</td></tr> 
          {{/each}}
      </tbody>
  </table>
</script>

<script type="text/x-handlebars" data-template-name="fast">
  <br/>
  <h2>Developer Profiles</h2>
  <table>
      <thead><th>First Name</th><th>Last Name</th></thead>
      <tbody>
          {{#each content}}
          <tr><td>{{firstName}}</td><td>{{lastName}}</td></tr> 
          {{/each}}
      </tbody>
  </table>
    {{#unless content.length}} <div class="loader">Loading</div> {{/unless}}
</script>

<script type="text/x-handlebars" data-template-name="loading">
    <div class="loader">Loading</div>
</script>

CSS

body { font-family: "Helvetica Neue"; font-weight: 300; margin: 15px; font-color: dimgray; }
a { margin-right: 15px; }
h1 { font-size: 1.6em; padding-bottom: 10px; }
h2 { font-size: 1.4em; }
th { border-bottom: 1px solid darkgray; }
th, td { padding: 10px 15px 10px 0; }

.loader {
  width: 100px;
  height: 100px;
  line-height: 100px;
  position: relative;
  box-sizing: border-box;
  text-align: center;
  z-index: 0;
  text-transform: uppercase;
}

.loader:before,
.loader:after {
  opacity: 0;
  box-sizing: border-box;
  content: "\0020";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 100px;
  border: 5px solid #888;
  box-shadow: 0 0 50px #ddd, inset 0 0 50px #ddd;
}

.loader:after {
  z-index: 1;
  -webkit-animation: gogoloader 2s infinite 1s;
}

.loader:before {
  z-index: 2;
  -webkit-animation: gogoloader 2s infinite;
}

@-webkit-keyframes gogoloader {
  0% {
    -webkit-transform: scale(0);
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(1);
    opacity: 0;
  }
}

JavaScript

var set = Ember.set;

window.App = Ember.Application.create({});

App.Fixture = {
    load: function() {
        var self = this;
        return new Ember.RSVP.Promise(function(accept, reject) {
            setTimeout(function() {
                accept([
                    { firstName: 'Kris', lastName: 'Selden' }, 
                    { firstName: 'Luke', lastName: 'Melia' },
                    { firstName: 'Formerly Alex', lastName: 'Matchneer' }
                ]);
            }, 2000);
        });
    }
};

App.Router.map(function() {
    ['fast', 'slow'].forEach(function(route) { 
        this.resource(route);
    }.bind(this));
});

App.SlowRoute = Ember.Route.extend({
    model: function() {
        return App.Fixture.load();
    }
});

App.FastRoute = Ember.Route.extend({
    model: function() {
        var model = Em.A([]);
        App.Fixture.load().then(function(content) {
            model.addObjects(content);
        });
        return model;
    }
});

App.SlowView = Ember.View.extend({ templateName: 'sample' });
App.FastView = App.SlowView.extend({ templateName: 'fast' });

App.IndexRoute = Ember.Route.extend();