[解決済み] AngularJS 。非同期データでサービスを初期化する
質問
私はいくつかの非同期データで初期化したいAngularJSサービスを持っています。このようなものです。
myModule.service('MyService', function($http) {
var myData = null;
$http.get('data.json').success(function (data) {
myData = data;
});
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
明らかに、これはうまくいきません。
doStuff()
の前に
myData
が戻ってくると、ヌルポインター例外が発生します。他の質問を読む限りでは
こちら
と
こちら
いくつかのオプションがありますが、どれもあまりきれいとは思えません(もしかしたら、私が何かを見逃しているのかもしれません)。
Run"でServiceをセットアップする。
私のアプリをセットアップするときは、こうしてください。
myApp.run(function ($http, MyService) {
$http.get('data.json').success(function (data) {
MyService.setData(data);
});
});
そうすると、私のサービスは次のようになります。
myModule.service('MyService', function() {
var myData = null;
return {
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData.getSomeData();
}
};
});
この方法でうまくいくこともありますが、非同期データがすべての初期化にかかる時間よりも長くかかるような場合、次のような例外が発生します。
doStuff()
プロミスオブジェクトを使用する
これならおそらくうまくいくでしょう。唯一の欠点は、MyServiceを呼び出すたびに、doStuff()がプロミスを返すことを知る必要があり、すべてのコードが以下のようになることです。
then
を使用して、プロミスと対話します。むしろ、myData が戻ってくるまで待ってからアプリケーションをロードしたいくらいです。
手動ブートストラップ
angular.element(document).ready(function() {
$.getJSON("data.json", function (data) {
// can't initialize the data here because the service doesn't exist yet
angular.bootstrap(document);
// too late to initialize here because something may have already
// tried to call doStuff() and would have got a null pointer exception
});
});
グローバルJavascriptバー JSONをグローバルなJavascript変数に直接送ることができるんだ。
HTMLで
<script type="text/javascript" src="data.js"></script>
data.jsです。
var dataForMyService = {
// myData here
};
を初期化する際に利用できるようになります。
MyService
:
myModule.service('MyService', function() {
var myData = dataForMyService;
return {
doStuff: function () {
return myData.getSomeData();
}
};
});
これもうまくいくのですが、グローバルなjavascript変数を持っていることになり、悪い匂いがします。
これしかないのでしょうか?どれか一つでも他の選択肢より優れているのでしょうか?これはかなり長い質問だと思いますが、私がすべての選択肢を探そうとしたことを示したかったのです。何かご指導いただければ幸いです。
どのように解決するのですか?
をご覧になりましたか?
$routeProvider.when('/path',{ resolve:{...}
? promiseのアプローチをもう少しすっきりさせることができます。
サービス内でプロミスを公開する。
app.service('MyService', function($http) {
var myData = null;
var promise = $http.get('data.json').success(function (data) {
myData = data;
});
return {
promise:promise,
setData: function (data) {
myData = data;
},
doStuff: function () {
return myData;//.getSomeData();
}
};
});
追加
resolve
をルート設定に追加してください。
app.config(function($routeProvider){
$routeProvider
.when('/',{controller:'MainCtrl',
template:'<div>From MyService:<pre>{{data | json}}</pre></div>',
resolve:{
'MyServiceData':function(MyService){
// MyServiceData will also be injectable in your controller, if you don't want this you could create a new promise with the $q service
return MyService.promise;
}
}})
}):
すべての依存関係が解決される前に、コントローラがインスタンス化されることはありません。
app.controller('MainCtrl', function($scope,MyService) {
console.log('Promise is now resolved: '+MyService.doStuff().data)
$scope.data = MyService.doStuff();
});
plnkrで例を作ってみました。 http://plnkr.co/edit/GKg21XH0RwCMEQGUdZKH?p=preview
関連
-
JavaScriptの関数この指摘の問題を説明
-
vueネットワークリクエストソリューション ネイティブネットワークリクエストとjsネットワークリクエストライブラリ
-
vueが定義するプライベートフィルタと基本的な使い方
-
[解決済み】Node.js getaddrinfo ENOTFOUND
-
[解決済み】JavaScript TypeError: null のプロパティ 'style' を読み取ることができない
-
[解決済み] jQueryでチェックボックスに "checked "を設定する
-
[解決済み] JavaScriptで現在のURLを取得する?
-
[解決済み] JavaScriptで要素のクラスを変更するにはどうすればよいですか?
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み] どうすればjQueryに非同期ではなく、同期のAjaxリクエストを実行させることができますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Vue+ElementUIによる大規模なフォームの処理例
-
vue+webrtc(Tencent cloud)ライブ機能の実践を実現するために
-
vueディレクティブv-bindの使用と注意点
-
[解決済み】SyntaxError: JSONの位置1に予期しないトークンoがある。
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み】ERROR エラーです。スイッチのname属性が指定されていないフォームコントロールの値アクセッサがない
-
[解決済み】ExpressJS - throw er Unhandled errorイベント
-
[解決済み】TypeScript-のAngular Frameworkエラー - "exportAsがngFormに設定されたディレクティブはありません"
-
[解決済み】ExpressJS : res.redirect()が期待通りに動かない?
-
HTML5 LocalStorage ローカルストレージとセッションストレージの使用法