2017-09-22 15 views
5

私の角型アプリケーションに1.6.5の角度を使用していて、非常に奇妙な動作が起こりました。ng-viewでng-classを更新していない

ngrouteが変更されているときは、現在のビューからアクティブなクラスを削除し、アニメーションを終了するのを待ってから、アクティブなクラスを新しいビューに追加する必要があります。

設定でアプリと経路を設定しました。

var app = angular.module('app', ['ngAnimate', 'ngRoute']); 

app.config(function ($routeProvider) { 
    $routeProvider 
     .when('/', { 
     templateUrl:"home.html", 
     reloadOnSearch:false 
     }) 
     .when('/about-us', { 
     templateUrl:"about.html", 
     reloadOnSearch:false 
     }) 
     .when('/contact', { 
     templateUrl:"contact.html", 
     reloadOnSearch:false 
     }) 
     .otherwise({ 
      template : "<h1>None</h1><p>Nothing has been selected</p>" 
     }); 
}); 

私はビューの可視性を示すアニメーションタイミングとブール値を格納するサービスがあります。私は、単純なデバッグ機能と電流からアクティブクラスを削除するべきものonRouteChangeStart機能を有する一つのメインコントローラを有する

app.service('animationProperties', function() { 
    this.animationTimings = { 
    views: 1000 
    }; 
    this.visibility = { 
    view : false 
    }; 
}); 

をビュー(ビューの可視性ブール偽にすることによって):

app.controller('MainCtrl', function ($scope, $window, $location, 
            animationProperties) { 

    $scope.animationProperties = animationProperties; 

    $scope.$on('$routeChangeStart',function() { 
    animationProperties.visibility.view = false; 
    }); 

    $scope.toggleActive = function(){ 
    $scope.animationProperties.visibility.view = !$scope.animationProperties.visibility.view; 
    } 
}); 

そして最後、ngAnimateが完了する休暇アニメーションを待ち、その後、()(doneメソッドで)現在のビューを削除し、真の可視性のブールを行うことにより、再び新しいビューに入る:あなたがいることがわかります(ナビゲーションから)ページを最初に切り替えるとき

ここ
app.animation('.view', function($timeout, animationProperties) { 
    return { 
    enter: function(element, done) { 
     $timeout(function() { 
     animationProperties.visibility.view = true; 
     $timeout(function() { 
      done(); 
     }, animationProperties.animationTimings.views);//Wait to enter 
     },animationProperties.animationTimings.views); //Wait for leave function 
    }, 
    leave: function(element, done) { 
     $timeout(function() { 
     done(); 
     }, animationProperties.animationTimings.views); 
    } 
    } 
}); 

plunker

ですすべて正常に動作しますが、ページに2回目に行くとビュークラスは更新されないため、アニメーションは再生されません。デバッグ中は、可視性ブール値が正しく更新されていることがはっきりと分かりますが、ビューを終了してもクラスは更新されません。

お手数をおかけします。

答えて

1

hereから自分自身を引用:$routeChangeStartオン

  1. は、あなたが(一度評価)という値を変更離れるactiveクラスを削除するngClassを教えてくれます:

    これは何が起こっているかでありますビュー。

  2. 同時に、$routeはテンプレートを取得することを含めて、入力ビューの準備を開始します。
  3. すべての準備ができたら、$routeChangeSuccessイベントをトリガします。このイベントは、ngViewが2つのビューのスワップを開始するように通知します。
  4. スワップ処理中に、ngViewは、離脱したビューのスコープを破棄します。その時点から、スコープのウォッチャは監視されなくなります。

の手順は1-4十分に速く起こる場合は、必要な表現がactiveクラスを削除するngClassについて評価される前に、そう、残しビューの範囲が破壊されます。 $routeは入力ビューのテンプレート(そのジョブを実行する時間はngClass)を要求する必要があるため、ルートを初めて訪れるとアニメーションが機能します。ただし、以前に訪問したルートにアクセスすると、テンプレートはすでにキャッシュされており、移行は高速です。


あなたは故意に(でもVMターンが十分である)テンプレート検索を遅くすることにより、この問題を回避することができます。たとえば:

​​

Updated plnkr 1

それを回避する別の方法、残しビューのスコープがある前に、クラスは、すぐに適用されるように、ngClassのあなた自身の、単純化し、同期バージョンを実装することです破壊されました。 CRUDは、そのような指示の最適化されていない、非生産対応バージョンは次のようになります。

:すべて言われていることを

app.directive('myClass',() => (scope, elem, attrs) => { 
    scope.$watchCollection(attrs.myClass, newValue => { 
    Object.keys(newValue).forEach(c => { 
     if (newValue[c]) { 
     elem.addClass(c); 
     } else { 
     elem.removeClass(c); 
     } 
    }); 
    }); 
}); 

Updated plnkr 2


、あなたは奇妙なセットアップのように思えます

  • イベント($routeChangeStart)を聞きます。
  • ngClassをトリガーにしてクラスを削除するフラグ(animationProperties.visibility.views)を設定します。
  • クラスを削除すると、CSSアニメーションがトリガーされます。
  • その間に、カスタムJavaScriptアニメーション(animation('.view'))をCSSアニメーションと同期させてから、フラグを元に戻します。
  • フラグを元に戻すことによって、入力ビューに対して反対のCSSアニメーションをトリガーします。手始めに

、なぜCSSやJSのアニメーションの両方を使用できますか?たとえば、JSアニメーションから不透明度の変更を処理することができます(実際の設定がより複雑で、他のエフェクトにはJSアニメーションが必要です)。スマイリー:)::

[ng-view].ng-enter { 
    /* Wait for the leaving view to...leave, then start transitioning in. */ 
    transition: opacity 1s ease 1s; 
} 

[ng-view].ng-leave { 
    /* Start transitioning out. */ 
    transition: opacity 1s ease; 
} 

[ng-view].ng-enter, 
[ng-view].ng-leave.ng-leave-active { 
    /* 
    * At the beginning of the entering animation and 
    * at the end of the leaving animation, 
    * the view must be fully invisible. 
    */ 
    opacity: 0; 
} 

[ng-view].ng-enter.ng-enter-active, 
[ng-view].ng-leave { 
    /* 
    * At the end of the entering animation and 
    * at the beginning of the leaving animation, 
    * the view must be fully visible. 
    */ 
    opacity: 1; 
} 

それとも、はるかに簡単に自動的に追加さに基づいて、純粋なCSSアニメーションでフェードイン/アウトを処理することができますが/それはわずか4小さなCSSルールをです(ng-enter/ng-leaveクラスを削除しました

Updated plnkr 3

関連する問題