2017-03-29 7 views
0

私はすでにこれを取り巻くグーグルをしていますが、うまくいくソリューションを見つけることができません。すべてのルート解決が完了するまで、ルートレベルでローディングインジケータを表示してください。

私はAngularJS 1.5.5と.NET Web API 2を使用してWebアプリケーションを構築していますが、すべての解決が完了するまでng-view要素を隠すだけです。

私はロードバーが表示され、変数がfalseされるまで内容を非表示にするには、インデックスのHTMLに使用されている$rootScopeに変数を設定する$routeChangeStart$routeChangeSuccessを使用しようとしています。ここで

はrouteChangeのプロパティのための私のルーティングコードです:私のhtmlを使用している、ここで

_app.config([ 
     '$routeProvider', '$httpProvider', '$provide', 
     function ($routeProvider, $httpProvider, $provide) { 
        $routeProvider.when('/Account', 
        { 
         templateUrl: '/Content/js/areas/account/account.html', 
         controller: 'accountController', 
         resolve: { 
          $accountResolver: function (accountService) { 
           return accountService.getMyAccountData(); 
          } 
         }, 
         caseInsensitiveMatch: true 
        }); 
      $routeProvider.otherwise({ redirectTo: '404' }); 

     } 
]); 

_app.run(['$rootScope', '$location', '$window', '$q', 'authService', 
     function ($rootScope, $location, $window, $q, authService) { 
      $rootScope.$on("$routeChangeStart", 
       function (e, curr, prev) { 
        $rootScope.$loadingRoute = true; 
       }); 
      $rootScope.$on("$routeChangeSuccess", 
       function (evt, next) { 
        $rootScope.$loadingRoute = false; 
       }); 
      $rootScope.$on("$routeChangeError", 
       function (evt, next) { 
        $rootScope.$loadingRoute = false; 
       }); 
     }]); 

そしてそれ$loadingRoute変数:私はカバーする記事のかなり多くがあることを理解し

<body class="ng-cloak" data-ng-app="wishlist" data-ng-controller="appController"> 
    <wl-header></wl-header> 
    <preloader ng-if="$loadingRoute"></preloader> 
    <section ng-view ng-if="!$loadingRoute" class="container ng-cloak"></section> 
</body> 

これは私の場合にはうまくいかないようです。 $loadingRouteは、<section></section>タグの前にHTMLに{{$loadingRoute}}を追加すると、ルート変更が開始されたときにtrueに設定されます。しかし、が解決される前に、$routeChangeSuccessが発生し、予想外の設定である$rootScope.$loadingRoute = falseが発生します。

私は、$routeChangeSuccessがすべての解決が現在のルートで完了した後にのみ起動したという印象を受けました。

私は本当にここで間違ったことをしていますか?またはAngularを単に変更しましたか?

編集:このアプローチは以前のプロジェクトでも機能していたので、私は何がうまくいかないのか本当に迷っています。私は$rootScope.$loadingRouteに手動で設定することはできますが、それはあまりにも汚いと維持できないと感じます。

編集2:

_app.factory('accountService', [ 
     'accountResource', 
     function (accountResource) { 
      var _self = this; 

      return { 
       register: function (authData) { 
        return accountResource.register(authData); 
       }, 

       getMyAccountData: function() { 
        return accountResource.getMyAccountData(); 
       } 
      } 
     } 
]); 

_app.factory('accountResource', [ 
     '$resource', 'rootUrl', 
     function ($resource, rootUrl) { 
      var api = rootUrl() + 'api/Account'; 
      return $resource(api, 
      {}, 
      { 
       register: { 
        method: 'POST', 
        url: '{0}/register'.format(api) 
       }, 
       getMyAccountData: { 
        method: 'GET', 
        url: '{0}/GetMyAccountData'.format(api) 
       } 
      }); 
     } 
    ]) 
+0

これがうまくいかない場合は、何か問題がありました。関連しているが投稿されていないコードが多すぎます。 accountServiceとaccountControllerはどこですか? – estus

+0

この状況では、コントローラ内のコードが解決後に実行されるため、AccountControllerは無関係です。サービスに関しては、getメソッドへの非常に単純なAngular $リソース呼び出しである 'accountResource.getMyAccountData()'を返しています。つまり、Web APIが応答を返した後に解決する約束を返します。 promiseが解決する前に '$ routeChangeSuccess'が起動していますが、これは間違っていると思います。サービスとリソースの中にほんの数行のコードを表示したいのであれば、私はそれらを共有することができます。 –

+0

getMyAccountDataが本当に約束を返すという証拠はありません。あなたが説明していることは、それが約束を返さなかった場合に可能であり、そうでなければ起こる可能性は非常に低いです。関連するすべてのコードを入力して、問題を再現できるplunk/fiddleを追加することを検討してください。 http://stackoverflow.com/help/mcveを参照してください。 – estus

答えて

1

リゾルバためには、ルート変更を遅らせるために、それは約束を返す必要があります。それ以外の場合は、すぐにルート変更が発生します。これは、accountService.getMyAccountData()の約束が解決される前に$routeChangeSuccessがトリガーされた場合に発生します。

問題は、$resourceメソッド(とaccountService.getMyAccountData())は、非同期的にデータが移入される自己充填オブジェクトを返します。このデータのための約束は$promiseプロパティとして利用可能である(the referenceを参照)ので、リゾルバを使用する必要があります。

$accountResolver: function (accountService) { 
    return accountService.getMyAccountData().$promise; 
} 

accountServiceを行うためのクリーンな方法、accountResourceための純粋な約束ベースのラッパーであるために仮定されている場合代わりにそのメソッドから約束を返すことです:

getMyAccountData: function() { 
    return accountResource.getMyAccountData().$promise; 
} 
+0

私の問題は、私がサービスで '$ promise'を返さなかったことでした。私はそれが私があなたの説明のおかげで逃した小さいものと思った! –

+0

ようこそ。 – estus

関連する問題