Ember中的全局变量

时间:2013-02-12 23:10:36

标签: ruby-on-rails ember.js ember-data

在Ember中存储全局变量的适当方法是什么?例如,我在Ember中有一个User模型,但我总是想知道该模型的哪个特定实例(包括其id,名称,电子邮件等)对应于当前登录的用户。

我应该以某种方式将它存放在Ember中吗?或者将JS变量附加到window对象(例如window.currentUserId = 1;)并使用它更好吗?

1 个答案:

答案 0 :(得分:8)

免责声明:以下所示的所有技巧都是我过去几个月与EmberJS的经历,以及与同事的一些讨论。如果不对劲,请提高声音。我们都在学习阶段(而且ember.js doc很糟糕,所以要善待;)

目前,我的工作场所有两位开发人员正在使用Ember.js。我们得出结论,将全局变量存储在全局ApplicationController中比在应用程序命名空间中存储要好得多。这是因为如果将该值存储在应用程序命名空间中,则该值的检索可能会非常混乱。这也适用于闭包,因此使全局命名空间清晰(并且相对无攻击)。您不希望用户执行App.set混乱变量吗?

这是基于1.0.0之前的版本。

考虑到你有这个currentUserId全局变量

  1. 存储在命名空间中。 jsFiddle demo

    (function() {
    
        function r() {
            return Math.round(Math.random()*999);
        }
    
        var MyApp = Ember.Application.create({
            currentUserId: null,
            ready: function() {
                //demo purpose.
                this.set('currentUserId', r());
            },
            rootElement: '#demo'
        });
        MyApp.ApplicationView = Ember.View.extend({
            templateName: 'application-view',
    
            //Direct child view
            innerView: Ember.View.extend({
                templateName: 'inner-view',
                setValue: function() {
                    this.set('controller.namespace.currentUserId', r());
                }
            }),
    
            //Direct child view, but with a controller attached
            innerViewWithController: Ember.View.extend({
                controller: Ember.Controller.create(),
                templateName: 'inner-view-with-controller',
                setValue: function() {
                    this.set('parentView.controller.namespace.currentUserId', r());
                }
            }),
            getValue: function() {
                alert(this.get('controller.namespace.currentUserId'));
            },
            setValue: function() {
                this.set('controller.namespace.currentUserId', r());
            }
        });
    })();
    
  2. vs存储在全球ApplicationController jsFiddle demo

    (function() {
    
        function r() {
            return Math.round(Math.random()*999);
        }
    
        var MyApp = Ember.Application.create({
            ApplicationController: Ember.Controller.extend({
                currentUserId: null,
                init: function() {
                    //demo purpose
                    this.set('currentUserId', r());
                }
            }),
            rootElement: '#demo'
        });
        MyApp.ApplicationView = Ember.View.extend({
            templateName: 'application-view',
    
            //Direct child view
            innerView: Ember.View.extend({
                templateName: 'inner-view',
                setValue: function() {
                    this.set('controller.currentUserId', r());
                }
            }),
    
            //Direct child view, but with a controller attached
            innerViewWithController: Ember.View.extend({
                controller: Ember.Controller.create(),
                templateName: 'inner-view-with-controller',
                setValue: function() {
                    this.set('parentView.controller.currentUserId', r());
                }
            }),
            getValue: function() {
                alert(this.get('controller.currentUserId'));
            },
            setValue: function() {
                this.set('controller.currentUserId', r());
            }
        });
    })();
    
  3. 请注意:

    1. 如果您选择存储在命名空间中,则需要始终通过根控制器访问它,因此它实际上与使用额外namespace关键字存储在applicationController中相同。

    2. 如果您选择将其存储在根applicationController中,对于来自applicationView的任何视图,您可以使用{{variableName}}轻松访问模板中的变量,而无需任何视图点遍历。默认情况下,Ember.Js通过控制器查找变量。

    3. 在最坏的情况下,如果您的内部视图需要拥有自己的控制器,那么通过根控制器(或命名空间)访问全局变量会更加痛苦,因为控制器没有链接,您需要遍历视图直到看到根控制器。在Ember.JS中,默认情况下,所有视图都将具有控制器集,默认情况下为父控制器。这意味着如果您从未指定任何控制器,则所有后代视图实际上都链接到根控制器。要解决此问题,您可以在控制器中执行变量绑定,以轻松解决遍历丑陋问题。

    4. 我不建议您在全局window对象中放置这么重要的变量,因为它很容易被用户修改(并引发任何潜在的问题)。将它放在ember应用程序命名空间中的全局命名空间中可以减少潜在的问题,但如果将其设置为全局

      则不会

      我的2美分;)