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

Jac*_*son 4 ember.js ember-data active-model-serializers

我对一个看似简单的余烬问题感到困惑.我正在使用active_model_serializers元数据序列化从rails控制器序列化我的rails current_user方法,然后使用这个人的临时解决方案提取并将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);
  }
});
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到这一点.现在,我可以通过键入App.metaData.current_user以及通过调用特定属性从句柄访问控制台中的current_user信息,即:

{{App.metaData.current_user.email}}
Run Code Online (Sandbox Code Playgroud)

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

currentUserBinding: 'App.metaData.current_user',

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

Ember.get('App.metaData.current_user')
Run Code Online (Sandbox Code Playgroud)

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

非常感谢任何帮助!

Mik*_*tti 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')
});
Run Code Online (Sandbox Code Playgroud)

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


Mil*_*Joe 6

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

<script type="text/javascript">
    window.user_id = 1;
</script>
Run Code Online (Sandbox Code Playgroud)

然后在您的应用程序中,您可以定义一个属性,该属性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));
    }
});
Run Code Online (Sandbox Code Playgroud)

然后你的模板,你可以使用属性ApplicationController#userInfo.

<script type="text/x-handlebars">
    <h1>App</h1>
    {{userInfo.fullName}}
</script>
Run Code Online (Sandbox Code Playgroud)

如果您需要使用路线中的这些数据,您可以使用controllerFor,或者如果您需要从另一个控制器访问,您可以使用needs.

(见小提琴)

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

  • 在将来,我想找出一种方法来通过json传递current_user,而不是将其嵌入到服务器端模板中,但现在这样做了!谢啦! (2认同)