Как запустить код после выполнения анимации javascript ввода / вывода ngView в AngularJS?

Я пытаюсь запустить функцию после анимации перехода страницы в AngularJS.

По сути, я пытаюсь добиться того, чтобы определенный код запускался в определенное время, например, после ввода перехода и до выхода из перехода.

Я использую ngRoute & ngView для переключения между представлениями и добавил анимацию Greensock в javavscript.

Любой совет по этому поводу?

Ниже мой код:

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


/**
 * Configuration
 */
MyApp.config( function($routeProvider) {

  $routeProvider
    .when('/', {
      controller: function($scope) {
        // I want to run a function only after the page transition is done
      },
      page_name: 'page-home',
      templateUrl: 'views-home.html'
    })
    .when('/about', {
      controller: function($scope) {
        // I want to run a function only after the page transition is done
      },
      page_name: 'page-about',
      templateUrl: 'views-about.html'
    })
    .otherwise({
      page_name: 'page-404',
      templateUrl: 'views-404.html'
    });

});


/**
 * Main controller
 */
MyApp.controller('mainController', function($animate, $scope, $route) {
  $scope.$route = $route;
});


/**
 * Page in & out animation
 */
MyApp.animation('.page-animation', function() {
  return {

    // Enter
    enter: function(element, done) {
      TweenMax.fromTo(
        element,
        2,
        {
          css: {
            transform: 'translateY(-100%)'
          }
        },
        {
          css: {
            transform: 'translateY(0%)'
          },
          ease: Expo.easeOut,
          onComplete: function() {
            done();
          }
        }
      );

      return function(is_cancelled) {
        if ( is_cancelled ) {
          TweenMax.set(
            element,
            {
              css: {
                transform: 'translateY(0%)'
              }
            }
          );
        }
      };
    },

    // Leave
    leave: function(element, done) {
      TweenMax.to(
        element,
        2,
        {
          css: {
            transform: 'translateY(100%)'
          },
          ease: Expo.easeOut,
          onComplete: done
        }
      );

      return function(is_cancelled) {
        if ( is_cancelled ) {
          TweenMax.set(
            element,
            {
              css: {
                transform: 'translateY(100%)'
              }
            }
          );
        }
      };
    }

  };
});

HTML:

<body ng-app="MyApp">

  <div ng-controller="mainController">
    <nav class="navigation">
      <ul class="">
        <li ng-class="{active: $route.current.page_name == 'page-home'}">
          <a href="#/">
            Home
          </a>
        </li>
        <li ng-class="{active: $route.current.page_name == 'page-about'}">
          <a href="#/about">
            About
          </a>
        </li>
      </ul>
      {{route}}
    </nav>

    <div ng-view class="page {{$route.current.page_name}} page-animation" done="console.log('hello world')"></div>

  </div>
  <script src="angular.min.js"></script>
  <script src="angular-route.min.js"></script>
  <script src="angular-animate.min.js"></script>
  <script src="TweenMax.min.js"></script>

  <script src="application.js"></script>
</body>

1 ответ

Решение

Хорошо, я понял это.

Я создал пользовательскую директиву, которая связывает обратный вызов с пользовательским событием, которое запускается по завершении анимации.

MyApp.directive('pageReady', function() {
  return function(scope, element, attrs) {
    scope.ready = false;

    element.bind('done', function() {
      scope.$apply(function() {
        scope.ready = true;
      });
    });

  };
});

Мы запускаем событие done после завершения анимации:

MyApp.animation('.page-animation', function() {
  return {

    // Enter
    enter: function(element, done) {
      TweenMax.fromTo(
        element,
        2,
        {
          css: {
            transform: 'translateY(-100%)'
          }
        },
        {
          css: {
            transform: 'translateY(0%)'
          },
          ease: Expo.easeOut,
          onComplete: function() {
            // Trigger done on the element, which our directive will pick up
            var event = new CustomEvent('done');
            element[0].dispatchEvent(event);
            done();
          }
        }
      );

      return function(is_cancelled) {
        if ( is_cancelled ) {
          TweenMax.set(
            element,
            {
              css: {
                transform: 'translateY(0%)'
              }
            }
          );
        }
      };
    }

  };
});

В нашем контроллере мы можем теперь наблюдать за scope.ready, чтобы быть правдой:

MyApp.controller('homeController', function($scope) {
  $scope.state = "Home page transitioning..";

  $scope.$watch('ready', function() {
    if ( $scope.ready ) {
      $scope.state = "Home page ready!"
    }
  });
});

Вы можете посмотреть рабочий пример здесь:
http://plnkr.co/edit/ZmZsnkPRK69UH9NUcSoh?p=preview

Другие вопросы по тегам