Ember.StateManager - Login Example

See: http://workmanw.github.com/emberjs-presentation

by fangyang

HTML

<script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.7.1.js"></script>
<!-- Logged Out View -->
<script type="text/x-handlebars" data-template-name="logged-out">
  <h1>Logged Out</h1>
  <hr /><br />
  <span>Login with "test/test"</span><br /><br />
  <label>Username: </label>{{view Ember.TextField valueBinding="MyApp.loginController.username"}}<br />
  <label>Password: </label>{{view Ember.TextField valueBinding="MyApp.loginController.password" type="password"}}<br />

  {{#if MyApp.loginController.isError}}
    <span class="login-error">Error: Invalid username or password.</span><br />
  {{/if}}
    
  <br /><button {{action "authenticate" target="MyApp.stateManager"}}>Login</button>
</script>

<!-- Logged In View -->
<script type="text/x-handlebars" data-template-name="logged-in">
  <h1>Logged In</h1>
  
  <hr /><br />
  <span>Welcome to your app!</span><br /><br />
  <button {{action "logout" target="MyApp.stateManager"}}>Logout</button>
</script>

CSS

body {
  padding: 8px;
}

h1 {
  font-size: 24px;
}

.login-error {
  color: red;
}

.ember-text-field {
  height: 16px;
  margin-bottom: 8px;
}

JavaScript

// MyApp namespace
window.MyApp = Ember.Application.create();

// Expect creditionals
MyApp.USERNAME = "test";
MyApp.PASSWORD = "test";

// Create the login controller
MyApp.loginController = Ember.Object.create({
  username: '',
  password: '',
  isError: false,
    
  tryLogin: function() {
    // Simulate server delay
    Ember.run.later(this, this._serverLogin, 100);
  },
    
  _serverLogin: function() {
    // Normally this would go to the server. Simulate that.
    if(this.get('username') === MyApp.USERNAME &&
       this.get('password') === MyApp.PASSWORD) {
      this.set('isError', false);
      this.set('username', '');
      this.set('password', '');
      MyApp.stateManager.send('loginSuccess');
    } else {
      this.set('isError', true);
      MyApp.stateManager.send('loginFail');
    }
  }
});    

// Create the logged out view class
MyApp.LoggedOutView = Ember.View.extend({
  templateName: 'logged-out'
});

// Create the logged in view class
MyApp.LoggedInView = Ember.View.extend({
  templateName: 'logged-in'
});

// Create the state manager
MyApp.stateManager = Ember.StateManager.create({
  initialState: 'loggedOut',
  
  // Logged out is a View State
  loggedOut: Ember.ViewState.create({
    initialState: 'awaitingCredentials',
    view: MyApp.LoggedOutView,

    awaitingCredentials: Ember.State.create({
      authenticate: function(manager, context) {
        manager.goToState('attemptingLogin');
      }
    }),

    attemptingLogin: Ember.State.create({
      enter: function() { 
        // Attempt server login
        MyApp.loginController.tryLogin();
      },
      loginSuccess: function(manager, context) {
        manager.goToState('loggedIn');
      },
      loginFail: function(manager, context) {
        manager.goToState('awaitingCredentials');
      }
    })
  }),
  
  // Logged in is also View State
  loggedIn: Ember.ViewState.create({
    view: MyApp.LoggedInView,
      
    logout: function(manager, context) {
     ...