これは2つの部分からなる質問です。
$ stateProvider.state()内のresolveプロパティを使用して、コントローラーをロードする前に特定のサーバーデータを取得しています。このプロセス中に表示する読み込みアニメーションを取得するにはどうすればよいですか?
また、resolveプロパティを利用する子状態があります。問題は、ui-routerがファイナライズを望んでいるように見えることですallコントローラーをロードする前に解決しますanyコントローラー。すべての子の解決を待つことなく、解決が解決された後に親コントローラーをロードする方法はありますか?これに対する答えはおそらく最初の問題も解決するでしょう。
編集:ここに、さらに簡単なソリューションがあり、テストされ、うまく機能しています:
私のメインコントローラーには
$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
if (toState.resolve) {
$scope.showSpinner();
}
});
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
if (toState.resolve) {
$scope.hideSpinner();
}
});
これは、状態の変更が完了したときに、解決するものがある状態に移動しようとしているときにスピナーを表示し、非表示にします。状態階層のチェックを追加することもできます(つまり、読み込まれている親状態が何かを解決する場合にスピナーを表示することもできます)が、この解決策はうまくいきます。
参照用および代替としての古い提案は次のとおりです。
アプリケーションコントローラーで、stateChangeStart
イベントをリッスンし、解決中にスピナーを表示する状態に切り替えようとしているかどうかを確認します( https://github.com/angular- ui/ui-router/wiki/Quick-Reference#wiki-events-1 )
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
if (toState.name == 'state.with.resolve') {
$scope.showSpinner(); //this is a function you created to show the loading animation
}
})
最終的にコントローラーが呼び出されたら、スピナーを非表示にすることができます
.controller('StateWithResolveCtrl', function($scope) {
$scope.hideSpinner();
})
また、エラーの処理中に$stateChangeError
イベントをリッスンし、アニメーションを非表示にすることにより、解決中に発生した可能性のあるエラーを確認することもできます。
スピナーのロジックをコントローラー間で分散するため、これは完全にクリーンではありませんが、方法です。それが役に立てば幸い。
私は完璧に機能する次のソリューションを開発しました。
1。次のapp.runを追加
app.run(function($rootScope){
$rootScope
.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
$("#ui-view").html("");
$(".page-loading").removeClass("hidden");
});
$rootScope
.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){
$(".page-loading").addClass("hidden");
});
});
2。ui-viewのすぐ上にロードインジケーターを配置します。id= "ui-view"をui-view divに追加します
<div class="page-loading">Loading...</div>
<div ui-view id="ui-view"></div>
。cssに以下を追加
.hidden {
display: none !important;
visibility: hidden !important;
}
注:
A.上記のコードは、2つの場合にロードインジケーターを表示します1) angularアプリが初めてロードされるとき2)ビューが変更されるとき.
B. angularアプリの初回ロード時(ビューがロードされる前)にインジケーターを表示したくない場合は、次のようにhidden classをロードdivに追加します未満
<div class="page-loading hidden">Loading...</div>
angular-loading-bar を使用すると、ネットワークアクセスが原因の長い解決に対して非常にうまく機能することがわかりました。
プロパティが解決されると、ui-routerによって入力されるコンテンツをdivに追加するのはどうですか?
あなたのindex.html
<div ui-view class="container">
Loading....
</div>
プロパティが解決されている間、ユーザーには「読み込み中...」と表示されます。すべての準備が整うと、コンテンツはアプリのコンテンツでui-routerに置き換えられます。
$http
に保留中のリクエストがある場合にのみ表示されるアニメーションgifを使用します。
基本ページテンプレートには、navbarおよびnavbarコントローラーがあります。コントローラーの関連部分は次のようになります。
controllers.controller('NavbarCtrl', ['$scope', '$http',
function ($scope, $http) {
$scope.hasPendingRequests = function () {
return $http.pendingRequests.length > 0;
};
}]);
私のhtmlに対応するコードは次のとおりです。
<span class="navbar-spinner" ng-show="hasPendingRequests()">
<img src="/static/img/spinner.gif">
</span>
それがお役に立てば幸いです!
私のアイデアは、$stateChangeStart
の状態の遷移間で状態グラフのパスをたどり、関係するすべてのビューを収集することです。次に、すべてのui-view
ディレクティブは、対応するビューが遷移に関与しているかどうかを監視し、その要素に'ui-resolving'
クラスを追加します。
plunker デモは、2つのルート状態を導入します:first
とsecond
、後者には2つのサブ状態second.sub1
とsecond.sub2
があります。状態second.sub2
は、その祖父母に属するfooter
ビューもターゲットにしています。
これは、ページが任意の状態(任意のページ)間をナビゲートするときにグローバルにローダーを使用し、app.jsに入れます
.run(
['$rootScope',
function($rootScope) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
$rootScope.preloader = true;
})
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
$rootScope.preloader = false;
})
}
])
HTMLで:
<div ng-show="preloader">Loading...</div>
主にコードベースをきれいに保つために、ロードアクティビティに一致するディレクティブを使用することを好みます
angular.module('$utilityElements', [])
.directive('loader',['$timeout','$rootScope', function($timeout, $rootScope) {
return {
restrict: 'A',
template: '<div id="oneloader" class="hiddenload">loading...</div>',
replace: true,
compile: function (scope, element, attrs) {
$timeout(function(){
$rootScope
.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
$("#oneloader").removeClass("hiddenload");
});
$rootScope
.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){
//add a little delay
$timeout(function(){
$("#oneloader").addClass("hiddenload");
},500)
});
}, 0);
}
}
}]);
$stateChangeStart
などの使用は非推奨になり、 移行フック に置き換えられました。したがって、Stefan Henzeの回答では、更新されたバージョンは次のようになります。
$transitions.onStart({}, function(transition) {
if (transition.to().resolve) {
$scope.showSpinner();
}
});
$transitions.onSuccess({}, function(transition) {
if (transition.to().resolve) {
$scope.hideSpinner();
}
});
親コントローラーでこれを使用できます。 $transitions
を挿入することを忘れないでください-
.controller('parentController',['$transitions',function($transitions){...}]);
また、空のオブジェクトであるresolve
は引き続きtransition.to().resolve == true
をレンダリングするため、状態宣言に空のプレースホルダーresolve
を残さないでください。
ルーターでresoleを使用しているときにビューを使用するという私の考えは、素晴らしい機能です。これを試して。
//edit index.html file
<ion-nav-view>
<div ng-show="loadder" class="loddingSvg">
<div class="svgImage"></div>
</div>
</ion-nav-view>
// css file
.loddingSvg {
height: 100%;
background-color: rgba(0, 0, 0, 0.1);
position: absolute;
z-index: 99;
left: 0;
right: 0;
}
.svgImage {
background: url(../img/default.svg) no-repeat;
position: relative;
z-index: 99;
height: 65px;
width: 65px;
background-size: 56px;
top: 50%;
margin: 0 auto;
}
// edit app.js
.run(function($ionicPush, $rootScope, $ionicPlatform) {
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams) {
$rootScope.loadder = true;
});
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams) {
$rootScope.loadder = false;
});
});
誰かがngRoute
を使用し、resolve
を待ってから次のビューをロードし、angular-bootstrap-ui
をuiに使用している場合、 以下 を実行できます。
app.config([
"$routeProvider", "$locationProvider", function($routeProvider, $locationProvider) {
return $routeProvider.when("/seasons/:seasonId", {
templateUrl: "season-manage.html",
controller: "SeasonManageController",
resolve: {
season: [
"$route", "$q", "$http", "$modal", function($route, $q, $http, $modal) {
var modal, promise, seasonId;
modal = $modal.open({
backdrop: "static",
template: "<div>\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n Loading...\n </h3>\n </div>\n <div class=\"modal-body\">\n <progressbar\n class=\"progress-striped active\"\n value=\"'100'\">\n </progressbar>\n </div>\n</div>",
keyboard: false,
size: "lg"
});
promise = $q.defer();
seasonId = $route.current.params.seasonId;
$http.get("/api/match/seasons/" + seasonId).success(function(data) {
modal.close();
promise.resolve(data);
}).error(function(data) {
modal.close();
promise.reject(data);
});
return promise.promise;
}
]
}
});
}
]);