将多个ui视图设置为一个

时间:2015-06-24 17:16:50

标签: angularjs angular-ui-router transition ng-animate

我有一个基本上看起来像这样的应用

<div ui-view="header">
<div ui-view="main">
<div ui-view="footer">

现在,页脚将对应用程序的所有不同状态保持不变,但标题将在某些状态中更改,但也会在许多州共享内容。唯一会在所有州内发生变化的ui-viewui-view="main"

目前我的$stateProvider看起来像这样(页脚尚未实现):

app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
  $stateProvider.state('root',{
      url: '',
      abstract: true,
      views: {
        'header': {
          templateUrl: appHelper.views+'/header.html',
        },
      }
    })
    .state('root.home', {
      url: '/',
      views: {
        'header': {
          templateUrl: appHelper.views+'/header.html',
        },
        'main@': {
          templateUrl: appHelper.views+'/home.html',
          controller: 'HomeController as homeVm',
        }
      },
      resolve: {
        posts: function(dataService) {
          return dataService.getPosts();
        },
        artists: function(dataService) {
          return dataService.getArtists();
        }
      }
    })
    .state('root.artist', {
      url: '/artist/:slug',
      views: {
        'header@': {
          templateUrl: appHelper.views+'/artistHeader.html',
          controller: 'ArtistController as artistVm',
        },
        'main@': {
          templateUrl: appHelper.views+'/artist.html',
          controller: 'ArtistController as artistVm',
        }
      },
      resolve: {
        artist: function($stateParams, dataService) {
          return dataService.getArtist($stateParams.slug);    
        }
      }
    });
}]);

到目前为止,这么好。但这是抓住了。在转换期间,我想将所有ui-view动画为一个。为了让事情在我的情况下看起来很有凝聚力(这是一个淡入淡出的动画)我想把它们放在一个包装div中并使div淡出/淡入(在每个不同的ui-view上做它会导致各种丑陋的)。

此方案中的最佳做法是什么?

我是否将它们包裹在ui-view中并以$stateProvider某种方式将其挂钩(嵌套ui-view?)。 有没有其他方法可以做到这一点?我可以收听$stateChange并将ngAnimate包装的类应用于ui-view吗? (淡出,然后等到完全消失,成功解决,然后逐渐消失)。

从我的谷歌搜索工作中,在处理过渡类型的动画时,似乎ui-view更受欢迎。

1 个答案:

答案 0 :(得分:3)

  

...在过渡期间,我想将所有ui视图设置为动画。要做   事情看起来很有凝聚力(这是一个淡出动画)我想   把它们放在一个包装div中,然后让div淡出/淡出   in(在每个不同的ui视图上执行它将导致各种各样的   uglyness)。

     

这种情况下的最佳做法是什么?

选项1:使用事件挂钩$stateChangeStart$stateChangeSuccess

这种方法会有一些副作用,正如@David在评论中提到的那样。因此,在ui-router提出更好的方法来管理状态转换承诺之前,请避免使用它。目前,它依靠event.preventDefault()来防止转变发生。

基本上,ui-router会在与传入的观看时同时触发您的ui-view路由更改视图。因此,您获得的是在呈现下一个ui-view时仍然可见的上一个ui-view,如果您要为查看设置动画,则旧视图和旧视图之间将存在重叠的转换持续时间。新的。您应该考虑暂停渲染新的ui-view,直到旧的ui-view完成动画制作(在制作动画之前)

出于类似的原因,将它们包装在另一个ui-view中并将它们挂在$stateProvider中并不明智。

选项2:(推荐)基于CSS的动画

我主要使用基于CSS的转换,你可以通过

来实现
  • 为每个ui-view分配一个公共CSS类,并在该类上应用动画。
  • 或将ui-view括在<div>中(如果你真的需要这个)并在其上应用动画。

无论哪种方式,你都会将所有ui-views视为一个单独的实体,动画它们会让事情看起来更具凝聚力。

HTML:

<div ui-view="header" ></div>    
<div ui-view="main" ></div>
<div ui-view="footer" ></div>

CSS:

[ui-view].ng-enter { 
   animation: fadein 2s;
}

@keyframes fadein {
    from { opacity: 0; }
    to   { opacity: 1; }
}

根据您的使用案例,我在这里工作plunkr,我有一个抽象状态root和三个嵌套状态root.homeroot.artist和{{1 }}。虽然root.band在所有州都发生了变化,但ui-view='main'在州&#39; root.artist&#39;的任何和ui-view='footer'更改中都没有变化。 您使用基于CSS的ui-view='header'.ng-enter类触发动画的事实,您在技术上克服了以前方法的问题。

.ng-leave