web-dev-qa-db-ja.com

angular ng-ifまたはng-showの応答が遅い(2秒の遅延?)

要求がビジーのときにボタンのロードインジケーターを表示または非表示にしようとしています。 angularを使用して、リクエストの読み込み中または読み込み完了時に$ scope.loading変数を変更します。

 $scope.login = function(){
     $scope.loading = true;
    apiFactory.getToken()
        .success(function(data){

        })
        .error(function(error){

        })
         .finally(function(){
               $timeout(function() {
                 $scope.loading = false;
               }, 0);
         });
 };

フロントエンドで:

<button ng-disabled="loading" class="button button-outline button-positive" type="submit">
Log in 
<span ng-if="loading" class="ion-refreshing"></span>
</button>

これは正常に機能しますが、ロードアイコン(イオン更新)は約2秒間表示され、$ scope変数はすぐに更新されます。私は$ scope。$ applyを試しましたが、それはここで間違っていることではないようです。スコープはリクエスト後すぐに正常に更新されます。十分に速く応答しないのはアイコンだけです。

これを理解するのを助けてくれてありがとう!

81
Jorre

アプリのconfigおよびindex.htmlページからngAnimateを使用していない場合は、削除してみてください。

angular.module('myApp', [...'ngAnimate',...])

@Spock;それでもngAnimateの使用が必要な場合は、アプリの設定をそのままにして、次のCSSを追加します。

.ng-hide.ng-hide-animate{
     display: none !important;
}

条件が満たされるとすぐにアニメーションアイコンが非表示になります。

ご覧のとおり、.ng-hide-animateをhiddenに設定しています。これが、アニメーションの完了を待機する際の遅延の原因です。上の例のようにクラス名を非表示にする代わりに、クラス名が示すように、hideイベントにアニメーションを追加できます。

121
Palvinder

私は同じ問題を抱えていましたが、ng-ifまたはng-show/ng-hideを使用する代わりに、「hidden」クラス名でng-classを使用して要素を非表示にすることで回避しました。

39
neimad

私はいくつかの解決策を見つけました ここ 、しかし、私にとって最善は、.ng-animateクラスのスタイルをオーバーライドすることでした:

.ng-animate.no-animate {
    transition: 0s none;
    -webkit-transition: 0s none;
    animation: 0s none;
    -webkit-animation: 0s none;
}

HTMLで:

<button ng-disabled="loading" class="button button-outline button-positive" type="submit">
    Log in 
    <span ng-if="loading" class="ion-refreshing no-animate"></span>
</button>

これは例です: http://jsfiddle.net/9krLr/27/

お役に立てば幸いです。

13
Ruben Perez

同様の問題に直面していたので、$scope.$evalAsync()を使用してバインディングを強制的に更新しました。

それは魅力のように機能します。

既に実行中の$ digestフェーズと競合する可能性があるため、$scope.$applyの使用は避けてください。

if(selectedStatistics.length === 0 || selectedWorkgroups.length === 0){
    ctrl.isSaveDisabled = true;
    $scope.$evalAsync();
} else{
    ctrl.isSaveDisabled = false;
    $scope.$evalAsync();
}
8
rach8garg

使用するときに同じ問題が発生しました

<div *ngIf='shouldShow'>
    <!-- Rest of DIV content here -->
</div>

私の場合、クラスを追加して解決しました:

.hidden {
  display: none;
}

*ngIfを使用する代わりに条件付きでクラスを追加します:

<div [ngClass]="{'hidden': !shouldShow}">
    <!-- Rest of DIV content here -->
</div>

常にこの方法で使用する場合は、shouldShowshouldHideに名前変更することを検討し(そして、それを割り当てるロジックを無効にします)、!shouldShowの代わりにshouldHideとして使用できます。

DIVの既存のクラスのCSSにdisplay: flexがある場合、その表示プロパティはdisplay: hiddenよりも優先される場合があります。代わりにdisplay: none !importantを使用すると簡単に修正できますが、多くの場合、他の方法で優先順位を確保するためのより良いソリューションがあります。 代替案についての良い読み物です

angularバージョン1.5.xで、条件の変更後に$scope.$apply()を追加すると、ここで私のために仕事が行われます

$scope.addSample = function(PDF)
        {
            var validTypes ="application/pdf";
            if(PDF.type == validTypes)
            {
                //checking if the type is Pdf and only pdf
                $scope.samplePDF= PDF.files[0];
                $scope.validError = false;
                $scope.$apply();
            }

            else
            {
                 $scope.validError = true;
                 $scope.samplePDF= null;
                 $scope.$apply();
            }


        }
0
mohamed