21

我有以下情况:我在 AngularJS 应用程序中使用 ui-router 进行路由。在一条路线中,不同的子屏幕有五个子状态。我想以类似轮播的方式为这些之间的过渡设置动画。

导航如下所示:

Link to A | Link to B | Link to C | Link to D | Link to E

state A从到导航state B应该使screen A向左screen B滑出并从右侧滑入;state B从到导航反之亦然state A

起作用的是仅在一个方向transform: translateX(...);上为屏幕过渡设置动画。enterleave

ng-class通常,我使用标志来控制我的动画。然而,在这种情况下,在ui-view元素上设置一个类根本不起作用(Angular 1.2 和 ui-router 0.2 还不完全兼容)。scope.$on "$stateChangeStart"它也不能使用在转换开始后触发的自定义指令来设置它。

如何实现所需的行为?

编辑:解决方案

为了记录:我最终使用自定义$scope函数来实现它$state.go(),用于在更改路线之前确定方向。这避免了$digest already in progress错误。确定动画的类被添加到ui-view的父元素中;这使当前和未来ui-view都朝着正确的方向发展。

控制器功能(Coffeescript):

go: (entry) ->
  fromIdx = ...
  toIdx = ...

  if fromIdx > toIdx
    $scope.back = false
  else
    $scope.back = true

  $state.go entry

模板:

<div ng-class="{toLeft: back}">
  <div ui-view></div>
</div>
4

5 回答 5

26

您可以通过专门设置控制器来控制视图上的类。然后,您可以订阅应用程序内的事件并更改页面动画方式。

<div class="viewWrap" ng-controller="viewCtrl">
  <div class="container" ui-view ng-class="{back: back}"></div>
</div>

然后在您的控制器中

.controller('viewCtrl', function ($scope) {
    $scope.$on('$stateChangeSuccess', function (event, toState) {
        if (toState.name === 'state1') {
            $scope.back = true; 
        } else {
            $scope.back = false; 
        }
    });
});

我已经设置了一个codepen来在这里演示http://codepen.io/ed_conolly/pen/aubKf

对于任何尝试这样做的人,请注意,由于 Angular 1.2 和 UI Router 中的动画当前不兼容,我不得不使用 ui.router.compat 模块。

于 2013-12-02T13:37:44.227 回答
3

您可以随时查看 angular-1.2 分支:https ://github.com/angular-ui/ui-router/tree/angular-1.2 。这修复了 ngAnimate 以及其他一些问题。

我相信这将包含在 ui-router 0.3.0 中,因此只要您不会很快推送直播,这应该会为您提供所需的功能,直到您可以回到“稳定”分支。

免责声明:我无权确定 UI-router 的下一个版本何时发布或包含哪些内容。我只是在 github 页面上的各种问题中找到了这些信息。

于 2013-12-03T17:26:47.387 回答
1

Eddiec 的解决方案是一个非常好的开始,但我仍然发现自己对它进行了一些修改。这是一个修改后的控制器,它更适合我的目的。这是更动态的:

function ViewCtrl($scope, $state) {

   $scope.$on('$stateChangeStart', function (event, toState) {
        var movingToParent = $state.includes(toState.name);
        if (movingToParent) {
            $scope.back = true; 
        } else {
            $scope.back = false; 
        }
    });


}
于 2015-03-17T16:34:21.517 回答
1

ngRoute我试图用using做同样的事情,$routeChangeSuccess但我遇到的问题是ng-leave动画会在摘要循环运行之前开始。进入动画总是正确的,但离开动画总是前一个。

对我有用的解决方案(Angular 1.57)是将$location.path()调用包装在$timeout. 这可确保在动画开始之前运行完整的摘要。

function goto(path) {
    if(nextIndex > currentIndex) {
      ctrl.transition = 'slide-out-left';
    } else {
      ctrl.transition = 'slide-out-right';
    }
    $timeout(function() {
      $location.path(path);
    });
  }
于 2016-07-10T21:47:47.123 回答
0

与@eddiec 接受的答案类似的尝试。基本上是状态名称值的数组,然后比较 toState 和 fromState 值的名称在数组中的位置以确定方向。

.controller('viewCtrl', function ($scope) { 
    $scope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {

        // create an array of state names, in the order they will appear
        var states = ['state1', 'state2', 'state3'];

        if (states.indexOf(toState.name) < states.indexOf(fromState.name)) {
          $scope.back = true; 
        } 
        else {
         $scope.back = false;  
        }
    });
});

Codepen,从上面分叉,显示工作结果。 http://codepen.io/anon/pen/zBQERW

于 2016-08-22T22:56:05.200 回答