【问题标题】:Ember controller seems to create multiple instances in template and route?Ember 控制器似乎在模板和路由中创建了多个实例?
【发布时间】:2014-04-05 09:41:55
【问题描述】:

我创建了一个小的jsfiddle,它不能使用 ember 1.5 和 handlebars 1.3 执行登录权限。登录控制器拥有一个设置为 true 的属性“isLogin”。但是为什么之后没有其他路由和模板注意到这个变化呢?

    <script type="text/x-handlebars">
    {{#if controllers.login.isLogin}}
    <div class="container">
      <div class="navbar">
        <div class="navbar-inner">
          <a class="brand" href="#">Ember Digest</a>
          <ul class="nav pull-right">
            <li>{{#link-to 'articles'}}Articles{{/link-to}}</li>
            <li>{{#link-to 'photos'}}Photos{{/link-to}}</li>
            <li>{{#link-to 'login'}}Login{{/link-to}}</li>
          </ul>
        </div>
      </div>
      {{outlet}}
    </div>
    {{/if}}
    {{render 'login' controllers.login.content}}
</script>

  <script type="text/x-handlebars" data-template-name="articles">
    <h2>Articles</h2>
  </script>


  <script type="text/x-handlebars" data-template-name="login">
    {{#if isLogin}}
      <p>You are already logged in!</p>
    {{else}}
      <form class="form-inline" {{action login on="submit"}}>
        <h2>Log In</h2>
        {{input class="btn" type="submit" value="Log In"}}
      </form>
      {{#if errorMessage}}
        <div class="alert alert-error">{{errorMessage}}</div>
      {{/if}}
    {{/if}}
  </script>

和js

App = Ember.Application.create();

// Routes
App.Router.map(function () {
    this.route('articles');
    this.route('photos');
    this.route('login');
});

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

App.AuthenticatedRoute = Ember.Route.extend({

    beforeModel: function (transition) {
        if (!this.controllerFor('login').get('isLogin')) {
            this.redirectToLogin(transition);
        }
    },

    redirectToLogin: function (transition) {
        alert('You must log in!');
        var loginController = this.controllerFor('login');
        loginController.set('errorMessage', 'Login first');
        this.transitionTo('login');
    }
});

App.ApplicationRoute = Ember.Route.extend({
    beforeModel: function (transition) {
        if (!this.controllerFor('login').get('isLogin')) {
            this.transitionTo('login');
        }
    }
});

App.LoginController = Ember.Controller.extend({
    isLogin: false,
    errorMessage: '',
    actions: {
        login: function () {
            alert("login");
            this.set('isLogin', true);
            this.transitionToRoute('articles');
        }
    }
});

App.ArticlesRoute = App.AuthenticatedRoute.extend({
    needs: 'login'
});

App.ApplicationController = Ember.Controller.extend({
    needs : 'login'
});

【问题讨论】:

    标签: javascript ember.js login-control


    【解决方案1】:

    我现在测试有点困难,但我认为您遇到了问题,因为您正在到达 路由层次结构。在大多数情况下,Ember 控制器/路由可以访问其父对象的属性,但不能访问其子对象。 (这是有道理的,因为父母可能是活跃的,而孩子却不是。)

    我认为不要将isLogin 属性放在LoginController 中,而是将它放在ApplicationController 中。然后,在你需要的地方,创建一个别名:

    App.ApplicationController = Em.ObjectController.extend({
        isLogin: false
    });
    
    App.LoginController = Em.ObjectController.extend({
        needs: ['application'],
        isLogin: Em.computed.alias('controllers.application.isLogin')
    });
    

    这更接近 Ember 习语,我认为可以解决您的问题。

    【讨论】:

    • 感谢您提供此内容。这很容易理解,但为了完整起见:您的第二个控制器应命名为“LoginController”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多