好的...回到绘图板上,我想出了这个很酷的方法,尽管我可能会与任何感兴趣的人分享。
首先让我们设置我们需要转换的状态。我只会用两个折叠面板而不是我拥有的三个来展示这个......无论如何它都会有很多代码,但值得分享的解决方案。
路由
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
order-checkout-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>
关闭状态.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>
order-confirmation-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
};
});
简而言之,我们在这里所做的是:
- 设置一个承诺,以了解我们何时可以再次过渡。
- 拦截 $stateChangeStart 事件并阻止它发生。
- 然后我们折叠我们感兴趣的面板
- 当折叠完成时,引导程序会触发一个事件,说我已经完成折叠,我们会监听它并依次解决承诺
- promise 解决后,我们可以安全地转换到下一个状态
我希望这不会太多,但如果你做到了,它对其他类型动画的潜力是相当大的。
我正在组装一个 plunker,以便可以看到动画。