プロミス(Config
ファクトリによって返された)が正常に解決されたときにのみインスタンス化されるトップレベルのコントローラーをセットアップしました。その約束は基本的に、RESTfulエンドポイントなどを使用して、Webアプリ構成をダウンロードします。
_$stateProvider
.state('app', {
url: '/',
templateUrl: 'views/_index.html',
controller: 'MainCtrl',
resolve: {
config: 'Config'
}
});
_
この設定により、下位のコントローラーが使用する前に、構成が適切にロードされていることを確認できます。
次に、より深くネストされたコントローラーに、factory
を使用し、解決された場合にのみ機能する別のConfig
を注入する必要があります(Webを必要とする_$resource
_ラッパーのように見える)サービスURL)。私が行った場合:
_$stateProvider
.state('app.bottom.page', {
url: '/bottom/page',
templateUrl: 'views/_a_view.html',
controller: 'BottomLevelCtrl',
resolve: {
TheResource: 'MyConfigDependingResource'
}
});
_
resolve
の評価順序は、コントローラの階層を上から下へとたどるのではなく、下から上へと続くように見えます。
app.bottom.page
_が入力されているui-router
_はMyConfigDependingResource
を解決しようとしますが、Config
が初期化されていないため、インジェクションは失敗しますui-router
_の解決が停止し(Error
sをスローすることさえありませんが、これは別の問題です)、Config
がトップレベルのコントローラーによって初期化されることはありません_ui-router
_が依存関係を逆の順序で解決するのはなぜですか? TheResource
オブジェクトをどのように簡単に解決できますかafterトップレベルMainCtrl
がConfig
を解決しました(_$inject
_に依存せずに、もちろん)?
[〜#〜] update [〜#〜]: this plnkr's log から、ネストされたコントローラーの後にのみ、最上位のresolve
が試行されていることがわかります独自の解決プロセスを開始しました。
@Kasper Lewauの回答と同様に、単一の状態の解決に対する依存関係を指定できます。解決の1つが同じ解決ブロックの1つ以上の解決プロパティに依存している場合。私の場合、checkS
は他の2つの解決策に依存しています
.state('stateofstate', {
url: "/anrapasd",
templateUrl: "views/anrapasd.html",
controller: 'SteofsteCtrl',
resolve: {
currU: function(gamMag) {
return gamMag.checkWifi("jabadabadu")
},
userC: function(gamUser, $stateParams) {
return gamUser.getBipi("oink")
},
checkS: ['currU', 'userC', 'gamMag', function(currU, userC, gamMag) {
return gamMag.check(currU, userC);
}]
}
})
** PS:** resolve
の内部動作の詳細については、 次のドキュメント の「解決」セクションを確認してください。
解決オブジェクトは並行して実行されるため、特定の階層に従いません。ただし、高次の解決オブジェクトを2次解決への依存関係として定義することにより、ネストされた解決が可能です。
$stateProvider
.state('topState', {
url: '/',
resolve: {
mainResolveObj: ['$someService', function ($someService) {
return 'I am needed elsewhere!';
}]
}
})
.state('topState.someOtherState', {
url: '/some-other-place',
resolve: {
someOtherResolveObj: ['mainResolveObj', function (mainResolveObj) {
console.log(mainResolveObj); //-> 'I am needed elsewhere!'.
}]
}
});
一種の悪い例ですが、私はあなたがそれの要点を得ると思います。上位レベルの解決オブジェクトの名前を下位レベルの解決への依存関係として定義すると、最初に解決されるまで待機します。
これは、低次のオブジェクトを解決する前に特定のデータをプリロードする方法と、認証要件(特に)を解決した方法です。
幸運を。
私は決議が連鎖すべきであることに同意します、そして私はこの領域の周りで多くの問題にぶつかりました。
しかし、そうではないので、私が思いついた解決策は、データが完成したときに解決するサービスに格納されている自分のプロミスを使用することです。私はあなたのplunkrを編集して機能するように最善を尽くしましたが、役に立ちませんでした。私はもうあなたのエラーにぶつかることはないので、うまくいけばこれから作業することができます: http://plnkr.co/edit/Yi65ciQPu7lxjkFMBKLn?p=preview
それがしていること:
設定を新しいpromiseオブジェクトと一緒に状態に保存します
myapp.service('state', function($q) {
this.load = $q.defer();
this.config = {}
})
最初の解決では、設定をこのサービスに保存し、準備ができたら、上で作成した新しいプロミスを解決します。
myapp.factory('Config', function($http, $log, state) {
return $http.get('example.json')
.then(function (data) {
angular.extend(state.config, data.data);
state.load.resolve();
});
});
最後の最も重要なステップは、上記の約束が解決されるまで、2番目の子をresolves関数のコンテンツと呼ばないことです。
myapp.factory('MyConfigDependingResource', function($log, state) {
return state.load.promise.then(function() {
if (!state.config.text) {
$log.error('Config is uninitialized!');
}
else {
// Do wonderful things
}
return
});
});
あなたが知っておく必要がある主なことは、設定が状態に保存されていることです。これを回避する方法はあるはずですが、これは以前に行った方法です。
連鎖させることはできませんが、別のものから呼び出すことができます。
var resolve2 = ['$stateParams',function($stateParams){
// do resolve 2 stuff
...
return true;
}];
var resolve1 = ['$stateParams',function($stateParams){
// do resolve 1 stuff
...
// now do resolve2 stuff
return $injector.invoke(resolve2,this,{$stateParams:$stateParams});
}];
$stateProvider.state("myState", {
resolve: {
resolve1: resolve1
}
});