私はコントローラ内のスコープ上の変数を初期化しているという問題があります。この変数は、ナビゲーションバーなどを制御するために使用され、ユーザーの種類に応じてサイトの一部へのアクセスを制限するので、その値を保持することが重要です。それに関する問題は、それを初期化するコントローラがなんらかの角度で再度呼び出されてから変数を初期値にリセットすることです。
これは大域変数を宣言して初期化する正しい方法ではなく、実際には大域的ではないと思います。正しい方法は何ですか、現在のバージョンのangleでうまく機能する例はありますか。
「グローバル」変数には、基本的に2つの選択肢があります。
$rootScope
http://docs.angularjs.org/api/ng.$rootScope を使用してください$rootScope
はすべてのスコープの親であるため、そこに公開されている値はすべてのテンプレートとコントローラに表示されます。 $rootScope
を使うのはとても簡単です。あなたはそれを任意のコントローラに挿入してこのスコープの値を変更することができるからです。便利かもしれませんが、すべての グローバル変数の問題 があります。
サービスは、任意のコントローラに注入し、それらの値をコントローラのスコープ内に公開できるシングルトンです。シングルトンであるサービスはまだ「グローバル」ですが、それらが使用され公開される場所をはるかにうまく制御できます。
サービスの使用はもう少し複雑ですが、それほど重要ではありません。以下に例を示します。
var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
return {
name : 'anonymous'
};
});
そして、コントローラで:
function MyCtrl($scope, UserService) {
$scope.name = UserService.name;
}
これが作業中のjsFiddleです。 http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/
Angularプロバイダーに関するドキュメント に従って、値を保存するだけの場合は、Valueレシピを使用する必要があります。
var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');
それからこのようなコントローラーでそれを使ってください:
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
this.clientId = clientId;
}]);
プロバイダ、ファクトリ、またはサービスを使用しても同じことが実現できます。これらは「プロバイダレシピの上にある単なる構文糖」だからです。ただし、Valueを使用すると最小限の構文で必要なものを実現できます。
他のオプションは$rootScope
を使うことですが、他の言語でグローバル変数を使うべきでないのと同じ理由で使うべきではないのでそれは本当にオプションではありません。控えめに使用するのは 推奨 です。
すべてのスコープは$rootScope
を継承しているので、あなたが変数$rootScope.data
を持っていて、誰かがdata
が既に定義されていることを忘れて、ローカルスコープで$scope.data
を作成すると、問題に遭遇します。
この値を変更してすべてのコントローラに渡って保持したい場合は、Javascriptが "参照のコピー" によって渡されることを念頭に置いてオブジェクトを使用し、プロパティを変更します。
myApp.value('clientId', { value: 'a12345654321x' });
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
this.clientId = clientId;
this.change = function(value) {
clientId.value = 'something else';
}
}];
$rootScope
を使用したAngularJS「グローバル変数」の例:
コントローラ1はグローバル変数を設定します。
function MyCtrl1($scope, $rootScope) {
$rootScope.name = 'anonymous';
}
コントローラ2はグローバル変数を読み取ります。
function MyCtrl2($scope, $rootScope) {
$scope.name2 = $rootScope.name;
}
ここで作業jsFiddleです: http://jsfiddle.net/natefriedman/3XT3F/1/ /
Wikiプールに別のアイデアを追加することに興味がありますが、AngularJSの value
と constant
modulesはどうですか。私はそれらを自分で使い始めたばかりですが、これらがおそらくここで最良の選択肢であるように思えます。
注:これを書いている時点では、Angular 1.3.7が最新の安定版です。これらは1.2.0で追加されたと思いますが、changelogでこれを確認していません。
いくつ定義する必要があるかに応じて、あなたはそれらのために別々のファイルを作成したいかもしれません。しかし、簡単にアクセスできるように、私は一般的にこれらを私のアプリの.config()
ブロックの直前に定義します。これらはまだ効果的なモジュールなので、それらを使用するには依存性注入に頼る必要がありますが、それらはあなたのアプリモジュールに対して "グローバル"と見なされます。
例えば:
angular.module('myApp', [])
.value('debug', true)
.constant('ENVIRONMENT', 'development')
.config({...})
その後、任意のコントローラの内側:
angular.module('myApp')
.controller('MainCtrl', function(debug, ENVIRONMENT), {
// here you can access `debug` and `ENVIRONMENT` as straight variables
})
最初の質問から、可変プロパティ(値)または最終プロパティ(定数)のいずれかとして、実際には静的プロパティが必要なようです。個人的な意見ではありませんが、ランタイム設定項目を$rootScope
に配置するのは面倒すぎて、早すぎます。
// app.js or break it up into seperate files
// whatever structure is your flavor
angular.module('myApp', [])
.constant('CONFIG', {
'APP_NAME' : 'My Awesome App',
'APP_VERSION' : '0.0.0',
'GOOGLE_ANALYTICS_ID' : '',
'BASE_URL' : '',
'SYSTEM_LANGUAGE' : ''
})
.controller('GlobalVarController', ['$scope', 'CONFIG', function($scope, CONFIG) {
// If you wish to show the CONFIG vars in the console:
console.log(CONFIG);
// And your CONFIG vars in .constant will be passed to the HTML doc with this:
$scope.config = CONFIG;
}]);
あなたのHTMLでは:
<span ng-controller="GlobalVarController">{{config.APP_NAME}} | v{{config.APP_VERSION}}</span>
localStorage.username = 'blah'
最新のブラウザを使用することが保証されている場合あなたの値がすべて文字列に変わることを知っていますが。
リロードの間にキャッシュされるという便利な利点もあります。
私の間違いであれば訂正してください。しかし、Angular 2.0がリリースされたとき、私は$rootScope
が周りにあるとは思わない。私の推測は、$scope
も削除されているという事実に基づいています。明らかにコントローラはまだ存在し、ng-controller
のようなやり方では存在しないでしょう。代わりにディレクティブにコントローラを注入することのヒント。リリースが間近に迫ってくるので、verison 1.Xから2.0への切り替えをもっと簡単にしたい場合は、グローバル変数としてサービスを使用するのが最善です。
環境変数$window
を使用して、コントローラの外側で宣言されているグローバル変数を$watch
の内側でチェックできるようにすることもできます。
var initWatch = function($scope,$window){
$scope.$watch(function(scope) { return $window.globalVar },
function(newValue) {
$scope.updateDisplayedVar(newValue);
});
}
ダイジェストサイクルはこれらのグローバルな値で長くなるので、リアルタイムで更新されるとは限りません。この設定でそのダイジェスト時間について調査する必要があります。
これを試してください、あなたはコントローラに$rootScope
を挿入することを強制しないでしょう。
app.run(function($rootScope) {
$rootScope.Currency = 'USD';
});
Configブロックでは$ rootScopeのサービスを使用するようには提供されないため、実行ブロックでのみ使用できます。
誤って別の方法を見つけたところです。
私は、var db = null
をアプリの宣言より上に宣言し、それをapp.js
に変更してからcontroller.js
にアクセスしたところ、問題なくアクセスできました。しかし、それは私が推測する良い解決策です。
それは実際にはかなり簡単です。 (とにかくAngular 2+を使用している場合)
単に追加する
declare var myGlobalVarName;
コンポーネントファイルの最上部のどこか( "import"ステートメントの後など)に配置すると、コンポーネント内の任意の場所で "myGlobalVarName"にアクセスできます。