ui-router状态转换动画的替代方法

时间:2014-04-23 07:07:57

标签: javascript angularjs animation angularjs-directive angular-ui-router

我的产品所有者在国家之间创建了一些动画,我认为这是一项几乎不可能实现的任务。我开始使用ngAnimate并想出了我认为对他的问题非常酷的解决方案 - 错误。

“这不是他告诉我的想法。”

所以要更好地勾画它。当我在折叠小部件的面板之间切换时,我想要更改状态并更新URL。

那么我怎样才能使用类似手风琴的方法或引导术语 - 崩溃小部件来动画状态转换?

1 个答案:

答案 0 :(得分:2)

好的......所以回到绘图板我想出了这个很酷的方法,虽然我可能会与感兴趣的人分享。

首先,我们可以设置我们需要转换的状态。我只会用两个折叠面板而不是我所拥有的三个面板来展示它......不管怎么说它会有很多代码,但是一个值得分享的解决方案。

<强>路由 app.js

        .state('home.checkout', {
            url: 'checkout',
            views: {
                '@home': {
                    templateUrl: 'views/partials/generic/checkout-process/order-checkout-root.html'
                }
            }
        })

        .state('home.checkout.shoppingcart', {
            url: '^/shoppingcart',
            views: {
                'shopping-cart@home.checkout': {
                    templateUrl: 'views/partials/generic/checkout-process/shoppingcart/shopping-cart-partial.html',
                    controller: 'ShoppingCartController'
                },
                'order-confirmation@home.checkout' : {
                    templateUrl: 'views/partials/generic/checkout-process/closed-state.html',
                    controller: function($scope) {
                        $scope.page = {name: 'Order Confirmation'};
                        $scope.state = {name: 'home.checkout.confirm'};
                    }
                }
            }
        })

        .state('home.checkout.confirm', {
            url: '/confirmation',
            views: {
                'shopping-cart@home.checkout': {
                    templateUrl: 'views/partials/generic/checkout-process/closed-state.html',
                    controller: function($scope) {
                        $scope.page = {name: 'Shopping Cart'};
                        $scope.state = {name: 'home.checkout.shoppingcart'};
                    }
                },
                'order-confirmation@home.checkout': {
                    templateUrl: '../views/partials/generic/checkout-process/confirmation/order-confirmation-partial.html',
                    controller: 'OrderConfirmationController'
                }
            }
        })

<强> HTML 顺序结帐-root.html

<div class="row checkout-process">
    <section class="col-sm-8 col-md-8 col-lg-8 panel-group" id="accordion">
        <div class="shopping-cart panel panel-default" ui-view="shopping-cart" autoscroll="false"></div>
        <div class="order-confirmation panel panel-default" ui-view="order-confirmation" autoscroll="false"></div>
    </section>
</div>

闭state.html

<article class="col-sm-12 col-md-12 col-lg-12 panel-heading closed-state">
    <h4 class="panel-title">
        <a ui-sref="{{state.name}}">
            {{page.name}}
        </a>
    </h4>
</article>

订单确认-partial.html

我只会包含这一个而不是其他部分因为它的想法相同。

<div class="order-confirmation-page row">
    <div class="panel-heading">
        <h4 class="panel-title">Order Confirmation</h4>
    </div>

    <div class="panel-collapse collapse" kx-collapse-toggler data-toggle="collapse">
        <div class="panel-body">
            <!--Code for the collapse body goes here-->
        </div>
    </div>
</div>

最后一部分重要的是要注意包含指令

kx-collapse-toggler

这是我们开展工作的地方,也是代码中最有趣的部分

<强> collapseTogglerDirective.js

'use strict';

angular.module('App.Directives.CollapseToggler', [])

    .directive('kxCollapseToggler', function ($rootScope, $state, $q, $timeout) {

        var linker = function(scope, element) {

            var
                collapse = $q.defer(),
                changeEventStarted = false
            ;

            //Expand the panel on directive instantiation
            $timeout(function() {
                $(element).collapse('show');
            }, 300);


            $rootScope.$on('$stateChangeStart', function(event, toState) {
                //Check to make sure we arent in the middle of a $stateChangeEvent
                if(changeEventStarted) {
                    return;
                }
                //Stop the state transition
                event.preventDefault();

                //Collapse the panel
                $(element).collapse('hide');

                //Wait for the panel to collapse completely
                collapse.promise.then(function() {
                    changeEventStarted = true;
                    //Then transiton the state
                    $state.transitionTo(toState);
                });
            });

            //Event listener for the collapse completed
            $(element).on('hidden.bs.collapse', function() {
                collapse.resolve();
            });
        };

        return {
            restrict: 'A',
            link: linker
        };
    });

简而言之,我们在这里做的是:

  1. 设定承诺,了解我们何时可以再次过渡。
  2. 拦截$ stateChangeStart事件并阻止它发生。
  3. 然后我们崩溃了我们感兴趣的小组
  4. 当崩溃完成后,bootstrap会发出一个事件,说我已经完成了崩溃,我们会倾听并反过来解决这个承诺
  5. 当承诺得到解决后,我们可以安全地过渡到下一个州
  6. 我希望这不是太多可以遵循,但如果你发挥其他类型的动画的潜力是非常好的。

    我正在努力整理一个plunker,以便能够看到动画。