Ember.js current_user - 从控制器访问全局变量

时间:2013-04-17 21:14:50

标签: ember.js ember-data active-model-serializers

我对一个看似简单的余烬问题感到困惑。我正在使用active_model_serializers meta data serialization从rails控制器序列化rails current_user方法,然后使用this guy's temporary solution提取并将current_user meta json设置为全局ember变量。

App.CustomRESTSerializer = DS.RESTSerializer.extend({
  extractMeta: function(loader, type, json) {
    var meta;
    meta = json[this.configOption(type, 'meta')];
    if (!meta) { return; }
    Ember.set('App.metaData', meta);
    this._super(loader, type, json);
  }
});

到目前为止一切都很好。现在,我可以通过键入App.metaData.current_user来访问控制台中的current_user信息,也可以通过调用特定属性从句柄中访问,即:

{{App.metaData.current_user.email}}

并且该电子邮件属性显示在模板中。当我尝试从ember控制器中访问该全局变量时,问题就出现了。这看起来非常简单,但我似乎无法从任何ember控制器中访问current_user。我试过了:

currentUserBinding: 'App.metaData.current_user',

currentUser: function() {
  return App.metaData.current_user;
}.property(),

Ember.get('App.metaData.current_user')

以及其他一些方法,但似乎无法访问它。奇怪的是,我可以通过直接路径从控制台和把手内轻松访问current_user,但不能从ember控制器中访问。我一定错过了一些明显的东西。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:7)

在我们的应用程序中,我们像@MilkyWayJoe建议的那样做,但我认为你的方法非常有趣。通过JSON传递current_user是一种非常优雅的方法。

我没有尝试太多,但从我在你的例子中可以看出,问题与序列化器无关。这是计算属性的问题 - 您需要指定它取决于App.metaData.current_user

App.ApplicationController = Ember.Controller.extend({
  currentUser: function() {
    return Ember.get('App.metaData.current_user')
  }.property('App.metaData.current_user')
});

这告诉ember它应该在App.metaData.currentUser更改时重新计算currentUser属性。否则它将运行fx一次(在你的ajax返回之前)并缓存响应。

答案 1 :(得分:6)

您可以定义一个变量来表示脚本标记中的用户ID。这应该在服务器模板中完成:

<script type="text/javascript">
    window.user_id = 1;
</script>

然后在您的应用中,您可以在ApplicationController中定义一个属性,该属性将存储当前用户模型,然后您可以find使用user_id变量:

window.App = Ember.Application.create();

App.store = DS.Store.create({
    revision: 12
});

App.User = DS.Model.extend({
    firstName: DS.attr('string'),
    lastName: DS.attr('string'),
    fullName: function() {
        return '%@ %@'.fmt(
            this.get('firstName'),
            this.get('lastName')
        );
    }.property('firstName', 'lastName')
});

App.ApplicationController = Em.Controller.extend({
    userInfo: null,
    init: function() {
        // this will fire a GET request to users_controller 
        this.set('userInfo', App.User.find(window.user_id));
    }
});

然后是您的模板,您可以使用ApplicationController#userInfo中的属性。

<script type="text/x-handlebars">
    <h1>App</h1>
    {{userInfo.fullName}}
</script>

如果您需要使用路线中的此数据,可以使用controllerFor,或者如果您需要从其他控制器访问,则可以使用needs

(见fiddle

请记住,这可能不是适用于所有方案的最佳解决方案,因为它会为您的应用初始化添加一个请求,但它现在可以解决这个问题。