EmberJS Router app: opinions against controllers

I am building a router-based EmberJS application (heavily modeled on excellent router guidance ). However, I am pretty confused about what applies to the view and the controller.

I fully understand that {{action showFoo}} often indicates a state change and that the router is the state machine for my application. But some of my actions do not fall into this category.

Here is an example from my actual code (html is simplified, but the mustache is untouched). I want to have a login form that works through ajax (i.e. the html form is not published directly on the server, it tells my eber application about an attempt to login through json).

<form> Email Name: {{view Ember.TextField valueBinding="email"}} Password: {{view Ember.TextField valueBinding="password"}} <button type="submit" {{ action logIn target="this" }}>Sign in</button> </form> 

The Bindings value is the fields in my loginController, but the logIn handler is in my opinion (because I could not figure out how to tell the template to call the controller). I feel this is a weird spread, and I'm not sure what Amber's right approach to this is.

I do not think that the router should handle the action because the request to try to log in is not a state change. LoginController feels like the right place to try login. After receiving a response to the input, this controller may cause a state change.

+7
source share
3 answers

I do not think that the router should handle the action because the request to try to log in is not a state change.

I think that is exactly the case: an attempt to login should go into authenticating state, where, for example, another click on "login" is ignored.

Therefore, IMHO must be handled by the router. I am thinking of something similar, see http://jsfiddle.net/pangratz666/97Uyh/ :

Steering wheels :

 <script type="text/x-handlebars" > {{outlet}} </script> <script type="text/x-handlebars" data-template-name="login" > <p class="info">{{message}}</p> Login to view the admin area <br/> Email: {{view Ember.TextField valueBinding="email" }} <br/> Password: {{view Ember.TextField valueBinding="password" }} <br/> <button {{action login}} >Login</button> </script> <script type="text/x-handlebars" data-template-name="authenticating" > Communicating with server ... </script> <script type="text/x-handlebars" data-template-name="admin" > Hello admin! </script> 

JavaScript :

 App = Ember.Application.create(); App.ApplicationController = Ember.Controller.extend({ login: function() { // reset message this.set('message', null); // get data from login form var loginProps = this.getProperties('email', 'password'); // simulate communication with server Ember.run.later(this, function() { if (loginProps.password === 'admin') { this.set('isAuthenticated', true); this.get('target').send('isAuthenticated'); } else { this.set('message', 'Invalid username or password'); this.set('isAuthenticated', false); this.get('target').send('isNotAuthenticated'); } }, 1000); // inform target that authentication is in progress this.get('target').send('authenticationInProgress'); }, logout: function() { this.set('isAuthenticated', false); } }); App.ApplicationView = Ember.View.extend({ templateName: 'application' }); App.LoginView = Ember.View.extend({ templateName: 'login' }); App.AdminView = Ember.View.extend({ templateName: 'admin' }); App.AuthenticatingView = Ember.View.extend({ templateName: 'authenticating' }); App.Router = Ember.Router.extend({ root: Ember.Route.extend({ index: Ember.Route.extend({ route: '/', loggedOut: Ember.Route.extend({ route: '/', connectOutlets: function(router) { router.get('applicationController').connectOutlet('login'); }, login: function(router) { router.get('applicationController').login(); }, authenticationInProgress: function(router) { router.transitionTo('authenticating'); } }), authenticating: Ember.State.extend({ enter: function(router) { router.get('applicationController').connectOutlet('authenticating'); }, isAuthenticated: function(router) { router.transitionTo('loggedIn'); }, isNotAuthenticated: function(router) { router.transitionTo('loggedOut'); } }), loggedIn: Ember.Route.extend({ route: '/admin', connectOutlets: function(router) { if (!router.get('applicationController.isAuthenticated')) { router.transitionTo('loggedOut'); } router.get('applicationController').connectOutlet('admin'); }, logout: function(router) { router.get('applicationController').logout(); } }) }) }) });โ€‹ 
+3
source

You can use the controller for this, your template has access to the controller.

 <script type="text/x-handlebars" data-template-name="loginTemplate"> {{#if controller.login}} Logged in! {{else}} Login failed {{/if}} </script> 

This script shows a small application that does the following: fiddle

Then, after logging in, you can make an actioncall for your router or show that the user has not logged in.

+1
source

I just did this by changing the codes as:

 {{ action logIn target="controller" }} 
+1
source

All Articles