【问题标题】:Ember.js current_user - accessing global variable from controllerEmber.js current_user - 从控制器访问全局变量
【发布时间】:2013-04-17 21:14:50
【问题描述】:

我对一个看似简单的 ember 问题感到困惑。我正在使用 active_model_serializers meta data serialization 从 rails 控制器序列化我的 rails current_user 方法,然后使用 this guy's temporary solution 提取该 current_user 元 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 信息,也可以通过调用特定属性从车把访问 current_user 信息,即:

{{App.metaData.current_user.email}}

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

currentUserBinding: 'App.metaData.current_user',

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

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

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

不胜感激!

【问题讨论】:

  • 在类似的场景中,我创建了一个User 模型并将其设置为ApplicationController 的属性,因此我可以通过我的路由中的controllerFor 或通过needs 访问我的控制器。
  • 那么从你的服务器你正在序列化一个用户对象,并在你的 ApplicationController 上设置一个 currentUser 属性,该属性绑定到类似 currentUser: App.User.find(0)?
  • 是的,请参见下面的示例。我还添加了一个带有模拟请求的小提琴

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


【解决方案1】:

在我们的应用程序中,我们按照@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 返回之前)并缓存响应。

【讨论】:

  • 太棒了,感谢您的帮助!现在我有两种方法工作。我试图避免在服务器端模板中嵌入 javascript,但是这种方法有什么好处吗?我倾向于坚持现在使用正确的计算属性的 JSON 序列化。
  • 我认为两者各有利弊。我们在 ember-data 支持元数据之前编写了我们的应用程序,因此没有考虑这种方法。 embed-in-server-side 的一个优点是,您不仅可以嵌入 current_user,还可以嵌入其他模型的数据,这可能比通过 api 获取 JSON 性能更好。
【解决方案2】:

您可以在脚本标签中定义一个变量来表示用户 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

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

【讨论】:

  • 将来我想找到一种通过 json 传递 current_user 的方法,而不是将其嵌入到服务器端模板中,但现在可行!谢谢大佬!
猜你喜欢
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
相关资源
最近更新 更多