在AngViewJS中完成ngView进入/离开javascript动画后如何运行代码?

时间:2014-05-29 12:04:33

标签: angularjs angularjs-animation

我试图在AngularJS中完成页面转换动画后运行一个函数。

基本上,我想要实现的是,在特定时间运行每个视图的特定代码,例如在进入转换&离开过渡之前。

我正在使用ngRoute& ngView在视图之间切换,并在javavscript中添加了我的Greensock动画。

对此有何建议?

在我的代码下面:

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 个答案:

答案 0 :(得分: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%)'
              }
            }
          );
        }
      };
    }

  };
});

在我们的控制器中,我们现在可以观察范围。已经是真的:

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