1
votes

first off, I'm a newbie to the world of EmberJS trying to explore and understand what's this framework is all about and I'm working with EmberJS version 1.0.0-rc2.

Problem Description


I have the following situation on a simple 'authentication' workflow where I want to pass values from one state to another on calling transitionTo, whereas the values should be taken from one view and passed into the other one also. to clarify my situation here a short description of the workflow (@Login and @Reset are representational for the corresponding route/controller/model/view components):

Workflow:

  • @Login: User tries to login with his credentials (account, username, password)
  • @Login: User failed to login because he forgot his password
  • @Login: User decides to reset his password and clicks on the link to get to the 'reset password' screen with the corresponding
  • @Reset: User has already filled out the values for 'username' and 'password' on the previous screen and therefore they are provided here
  • User just has to click on the button to get a mail for the password reset link.

so, as I have understand it, I should handle all things which are changing the state (navigate from 'login' to 'reset') within the Route, things such as the login or reset action should be handled within the Controller.

now, I want to pass the values for 'account' and 'password' from the @Login Route to the @Reset Route. I'm not able to access the View from the Route nor from the Controller, but I'm able to access the Controller from the Route, so I thought about handling the reset action in the Controller to get the values for both fields and call a method on the Route which then will execute the transitionTo method. is this a correct way of achieving this behaviour?

I'll give a little code example, perhaps it will help to see things clearer:

Code


LoginController:

App.LoginController = Ember.ObjectController.extend({
account: null,
username: null,
password: null,
submitLogin: function () {
  $.ajax({
    type: 'POST',
    url: 'authentication/login',
    data: { 
      account: this.get(account), 
  username: this.get(username), 
  password: this.get(password)
    },
    success: function (data, status) {
      var dStat = data.status.toString().toLowerCase();

      if (dStat == 'ok') {
        window.location.assign(data.data.redirect);
      } else if (dStat == 'warning') {
        console.warn(dStat + data.message);
      } else if (dStat == 'error') {
        console.error(dStat + data.message);
      }
    },
    error: function (xhr, ajaxOptions, thrownError) {
      console.error('Got an ERROR on Ajax Request!');
      console.error('Status (' + xhr.status + ') - Error: ' + thrownError);
    }
  });
},

requestReset: function() {
  this.get('target').send('reset', { account: this.get('account'), username:  this.get(username)}); // <-- this is NOT working
}
});

LoginRoute:

LoginRoute = Ember.Route.extend({
  renderTemplate: function () {
  this.render('authentication-login',
    {
      outlet: 'main'
    });
  },

  events: {
    reset: function (args) {
      this.transitionTo('authentication.reset', args); // <-- does it work?
    }
  }
});

Question


am I on the right path by chaining the actions like view --> controller --> route (transitionTo) --> otherRouter --> otherController --> otherView ? what is the "Ember Way" of doing this?

UPDATE 1:


if I try to declare the dependency between my two Controllers like @MikeGrassotti suggested

App.LoginRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render('login', { outlet: 'main' });
  },

  events: {
    reset: function() {
      this.transitionTo('reset');
    }
  }
});

App.LoginController = Ember.ObjectController.extend({
  account: null,
  username: null,
  password: null,

  login: function() {

  }
});


App.ResetRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render('reset', { outlet: 'main' });
  }
});

App.ResetController = Ember.ObjectController.extend({
  needs: ['login'],
  accountBinding: 'controllers.login.account',
  usernameBinding: 'controllers.login.username'
});

I get the following error message:

Uncaught Error: assertion failed: Cannot delegate set('account', (null)) to the 'content' property of object proxy <App.ResetController:ember198>: its 'content' is undefined

if I just declare the needs property for the ResetController and call controllers.login.account from the corresponding template I get no error, but I also get no value (given I typed 'asdf' as value into the account field of the login form)...

1

1 Answers

3
votes

am I on the right path by chaining the actions like view --> controller --> route (transitionTo) --> otherRouter --> otherController --> otherView ?

Yes in terms of transitioning, but no in terms of trying to pass parameters. The only time you should be passing args in a transitionTo is when a context is needed as in transitionTo('post', somePost)

I want to pass the values for 'account' and 'password' from the @Login Route to the @Reset Route. what is the "Ember Way" of doing this?

Instead of passing values from one route to another, use bindings to access properties of your controllers. For example:

App.ResetController = Ember.ObjectController.extend({
  needs: ['login'],
  accountBinding: 'controllers.login.account',
  usernameBinding: 'controllers.login.username'
});

Now just use transitionTo('reset') with no args to switch to the reset route.