我正在创建一个基于路由器的EmberJS应用程序(强烈建模在
excellent router guide上).但是,我对视图中的属性和控制器中的内容非常混淆.
我完全得到{{action showFoo}}经常表示状态更改,并且路由器是我的应用程序的状态机.但我的一些行为并不属于这一类.
这是我实际代码中的一个例子(简化了html但是完整的胡子).我希望有一个通过ajax工作的登录表单(即html表单不直接发布到服务器,它告诉我的ember应用程序尝试通过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>
valueBindings是我的loginController中的字段,但是logIn处理程序在我的视图中(因为我无法弄清楚如何告诉模板调用控制器).我觉得这是一个奇怪的分布&我不确定正确的Ember方法是什么.
我不认为路由器应该处理该操作,因为请求登录尝试实际上不是状态更改. loginController感觉就像是尝试登录的正确位置.收到登录响应后,该控制器可以触发状态更改.
解决方法
I don’t think the router should be handling the action because requesting a login attempt isn’t really a state change.
我认为情况确实如此:尝试登录应该转换到身份验证状态,例如,忽略另一次点击“登录”.
所以恕我直言,这应该由路由器处理.我正在考虑这样的事情,见http://jsfiddle.net/pangratz666/97Uyh/:
把手:
<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(); } }) }) }) });