12

Angularjs の FEQ を調べているときに、以下の記事を見ました。

$rootScope は存在しますが、悪用される可能性があります

Angular のスコープは階層を形成し、プロトタイプとしてツリーの最上部にあるルート スコープから継承します。ほとんどのビューには独自のコントローラー、つまりスコープがあるため、通常、これは無視できます。

場合によっては、アプリ全体に対してグローバルにしたいデータの断片があります。$rootScopeこれらについては、他のスコープと同様に値を挿入して設定できます。ng-showスコープはルート スコープから継承するため、これらの値は、 local の値と同様に、ディレクティブに関連付けられた式で使用できます$scope

もちろん、グローバルな状態は最悪であり$rootScope、(できれば) どの言語でもグローバル変数を使用するように、慎重に使用する必要があります。特に、コードには使用せず、データのみに使用してください。に関数を配置したい場合は$rootScope、ほとんどの場合、必要な場所に挿入でき、より簡単にテストできるサービスに配置することをお勧めします。

逆に、データのビットを保存して返すことだけを目的とするサービスを作成しないでください。

— AngularJS FAQ - $rootScope は存在しますが、悪用される可能性があります

だから私の疑問は、なぜ $rootScope がグローバル関数としての関数に推奨されないのですか? パフォーマンスの問題はありますか?

4

3 に答える 3

3

グローバル変数の悪用

$rootScopeほとんどグローバル変数であり、その場所がありますが、それを使用するほとんどの人によって間違いなく悪用されています. これらが、一般にグローバルを使用すべきではない理由です。

非局所性-- ソース コードは、個々の要素の範囲が限定されている場合に最も理解しやすくなります。グローバル変数は、プログラムのどの部分でも読み取ったり変更したりできるため、考えられるすべての用途を覚えたり推論したりすることが難しくなります。

アクセス制御や制約チェックなし-- グローバル変数はプログラムのどの部分からでも取得または設定でき、その使用に関する規則は簡単に破られたり忘れられたりする可能性があります。(つまり、get/set アクセサーは直接データ アクセスよりも一般的に好まれており、これはグローバル データの場合はなおさらです。) さらに言えば、アクセス制御の欠如は、信頼されていないコードを実行したい状況でのセキュリティの実現を大きく妨げます。 (サードパーティのプラグインの操作など)。

暗黙の結合-- 多くのグローバル変数を含むプログラムでは、多くの場合、これらの変数の一部が密接に結合され、変数と関数が結合されます。結合された項目をまとまりのある単位にグループ化すると、通常、より良いプログラムにつながります。

並行性の問題-- グローバルが複数の実行スレッドからアクセスできる場合、同期が必要です (そして、あまりにも頻繁に無視されます)。モジュールをグローバルに動的にリンクする場合、数十の異なるコンテキストでテストされた 2 つの独立したモジュールが安全であっても、構成されたシステムはスレッドセーフではない可能性があります。

名前空間の汚染-- グローバルな名前はどこでも利用できます。ローカルを使用していると思っているときに (つづりを間違えたり、ローカルの宣言を忘れたりして)、無意識のうちにグローバルを使用してしまう場合や、その逆の場合もあります。また、同じグローバル変数名を持つモジュールをリンクする必要がある場合、運が良ければリンク エラーが発生します。運が悪いと、リンカは同じ名前のすべての使用を同じオブジェクトとして単純に扱います。

メモリ割り当ての問題-- 一部の環境には、グローバルの割り当てを難しくするメモリ割り当てスキームがあります。これは、「コンストラクター」が割り当て以外の副作用を持つ言語で特に当てはまります (その場合、2 つのグローバルが相互に依存する危険な状況を表現できるため)。また、モジュールを動的にリンクする場合、異なるライブラリに独自のグローバル インスタンスがあるかどうか、またはグローバルが共有されているかどうかが不明な場合があります。

テストと閉じ込め- グローバルを利用するソースは、実行の間に「クリーンな」環境を簡単に設定できないため、テストがやや難しくなります。より一般的には、ソースに明示的に提供されていない何らかのグローバル サービス (ファイルやデータベースの読み取りと書き込みなど) を利用するソースは、同じ理由でテストが困難です。通信システムの場合、システムの不変条件をテストするには、システムの複数の「コピー」を同時に実行する必要がある場合があります。これは、テストの一部として共有するために提供されていない共有サービス (グローバル メモリを含む) の使用によって大きく妨げられます。 .

ソース: http://c2.com/cgi/wiki?GlobalVariablesAreBad

Angular でデータを共有する

Angular でコントローラー間でデータを共有する場合は、サービスを使用する必要があります。カスタム サービスを使用して、ゲッター メソッドとセッター メソッドを作成できます。必要なコントローラーにそれを注入し、アプリで使用できます。

于 2015-09-24T12:55:30.160 に答える
1

パフォーマンスの問題はありません。多くのサービスに依存性を注入する必要がないため、実際にはパフォーマンスがわずかな時間で向上します。

しかし、それはデザイン上の大きな問題です。数十ものビュー、複雑なコンポーネントを持ち、多くのよく知られた API (Twitter、Flickr、Facebook、OAuth など) に関連付けられた大規模なアプリケーションを考えてみましょう。

このアプリケーションを単独で開発することはありません。次の問題が発生します。

名前空間

あなたは Facebook API に取り組んでおり、他の誰かが Twitter API に取り組んでいます。$rootScope2 人ともfor 関数を使用するのは良い考えだと思い、2 人とも$rootScope.login関数を作成します。するときにこれをどのように解決しgit mergeますか? 残念ながら、名前空間が必要です。2 つのサービスを開発する必要がありますmyFacebookAPImyTwitterAPIこれにより、ログイン用の同じインターフェイスを実装できます ( login(user,pw))。これにより、次のようなことができる場合、コントローラーで扱っている実際のソーシャル ネットワークを抽象化することができることに注意してください。

$scope.callAction = function (action) {
var service;
    if ($scope.serviceSelected === 'fb') {
         service = myFacebookAPI;
    } else {
         service = myTwitterAPI;
    }
    service[action]();
};

テスト

専門的に開発するときは、テストを作成します。$rootScopeAngular は、サービスなどの自動テストを行うためのツールを提供しますが、割り当てたものを同じ快適な方法でテストすることはできません。

他の問題も発生しますが、これはあなた自身で考えるのに十分であると思います.

于 2015-09-24T13:32:40.147 に答える