6

グローバル変数をEmberに格納するための適切な方法は何でしょうか?たとえば、Emberにユーザーモデルがありますが、そのモデルのどの特定のインスタンス(ID、名前、電子メールなどを含む)が現在ログインしているユーザーに対応するかを常に知りたいです。

どういうわけかこれをEmber内に保存する必要がありますか?または、JS変数をwindowオブジェクト(たとえばwindow.currentUserId = 1;)にアタッチしてそれを使用する方が良いですか?

4

1 に答える 1

8

免責事項:以下に示すすべてのテクニックは、過去数か月間のEmberJSでの私の経験と、同僚とのいくつかの議論です。何か間違っている場合は、声を上げてください。私たちは皆学習段階にあります(そしてember.jsのドキュメントはmaxxxに吸い込まれているので、親切にしてください;)

現在、私の職場にはEmber.jsを使用している2人の開発者がいます。ApplicationControllerグローバル変数をグローバルに格納する方が、アプリケーションの名前空間に格納するよりもはるかに優れているという結論に達しました。これは、この値がアプリケーションの名前空間に格納されている場合、この値の取得が非常に面倒になる可能性があるためです。そして、これはクロージャーでもうまく機能するため、グローバル名前空間をクリーンにします(そして比較的ハックフリーにします)。App.setユーザーが変数をいじくりまわしたくないですか?

これは、1.0.0pre-4に基づいています。

currentUserIdこのグローバル変数があることを考えると

  1. 名前空間に保存します。jsFiddleデモ

    (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デモへの保存

    (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());
            }
        });
    })();
    

ご了承ください:

  1. namespace名前空間に格納することを選択した場合は、常にルートコントローラを介してアクセスする必要があるため、実際には、追加のキーワードを使用してapplicationControllerに格納するのと同じです。

  2. ルートに格納することを選択した場合applicationController、から派生するビューについては、ドットトラバーサルなしapplicationViewでテンプレート内の変数に簡単にアクセスできます。{{variableName}}デフォルトでは、Ember.Jはコントローラーを介して変数を検索します。

  3. 最悪の場合、内部ビューに独自のコントローラーが必要な場合、コントローラーがリンクされていないため、ルートコントローラー(または名前空間)を介してグローバル変数にアクセスするのは少し面倒です。ルートが表示されるまでビューをトラバースする必要があります。コントローラ。Ember.JSでは、すべてのビューにデフォルトでコントローラーが設定され、デフォルトでは親のコントローラーが設定されます。つまり、コントローラーを指定しない場合、すべての子孫ビューは実際にはルートコントローラーにリンクされます。この問題を克服するために、コントローラーで変数バインディングを実行して、トラバースの醜さを簡単に解決できます。

このような重要な変数をグローバルwindowオブジェクトに配置することはお勧めしません。ユーザーが簡単に変更できるためです(潜在的な問題が発生します)。emberアプリケーションの名前空間のグローバル名前空間に配置すると、潜在的な問題は軽減されますが、グローバルに設定した場合は軽減されません。

私の2セント;)

于 2013-02-13T04:24:37.547 に答える