将多个ui视图设置为一个动画的最佳实践

INT*_*INT 8 transition angularjs ng-animate angular-ui-router

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

<div ui-view="header">
<div ui-view="main">
<div ui-view="footer">
Run Code Online (Sandbox Code Playgroud)

现在,页脚将对应用程序的所有不同状态保持不变,但标题将在某些状态中更改,但也会在许多州共享内容.唯一ui-view会改变所有州的是ui-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);    
        }
      }
    });
}]);
Run Code Online (Sandbox Code Playgroud)

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

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

我是否将它们包装在一起ui-view$stateProvider以某种方式挂钩(嵌套ui-view的?).有没有其他方法可以做到这一点?我可以听$stateChange和喜欢应用类,我的包装ngAnimate像使用ui-view?(淡出,然后等到完全消失,成功解决后才能消失).

从我的谷歌搜索努力来看,ui-view在处理过渡类型的动画时似乎更受欢迎.

nal*_*inc 3

\n

...在转换过程中,我想将所有 ui 视图作为一个动画。为了使\n在我的情况下看起来有凝聚力(它\xe2\x80\x99s是一个淡入淡出动画),我想\n将它们放在一个包装div中,并让该div执行淡出/淡出\nin(在每个不同的ui-view 会导致各种\nuglyness)。

\n

这种情况下的最佳实践是什么?

\n
\n

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

\n

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

\n

基本上,ui-routerui-view在传入视图的同时触发您的路线更改视图。因此,您得到的是前一个ui-view仍然可见,而下一个已ui-view渲染,如果您要对视图进行动画处理,那么旧视图和新视图之间将存在重叠的过渡持续时间。您应该考虑推迟渲染新的 ui-view,直到旧的 ui-view 完成动画输出(在新的 ui-view 动画进入之前)

\n

出于类似的原因,将它们包裹在另一个中ui-view并将它们连接起来$stateProvider并不明智。

\n

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

\n

我主要使用基于 CSS 的过渡,你可以通过以下方式实现这一点

\n
    \n
  • 为每个类分配一个公共 CSS 类ui-view并在该类上应用动画。
  • \n
  • 或者将这三个包含ui-view在 a 中<div>(如果您确实需要的话)并在其上应用动画。
  • \n
\n

无论哪种方式,您都会将所有内容ui-views视为一个实体,并且对它们进行动画处理会让事情看起来更有凝聚力。

\n

HTML:

\n
<div ui-view="header" ></div>    \n<div ui-view="main" ></div>\n<div ui-view="footer" ></div>\n
Run Code Online (Sandbox Code Playgroud)\n

CSS:

\n
[ui-view].ng-enter { \n   animation: fadein 2s;\n}\n\n@keyframes fadein {\n    from { opacity: 0; }\n    to   { opacity: 1; }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是一个基于您的用例的工作plunkr ,其中我有一个抽象状态root三个嵌套状态root.homeroot.artistroot.band虽然ui-view=\'main\'所有状态都会发生变化,但状态“root.artist”ui-view=\'footer\'不会发生任何变化。\n事实上,您使用基于 css和类来触发动画,从技术上讲,您克服了以前方法的问题。ui-view=\'header\'.ng-enter.ng-leave

\n
  $stateProvider\n        .state(\'root\',{\n          abstract:true,\n            views:{\n              \'header\':{  //absolutely targets the \'header\' view in root unnamed state.\n                templateUrl:\'header.html\'\n              },\n              \'footer\':{  //absolutely targets the \'footer\' view in root unnamed state.\n                templateUrl:\'footer.html\'\n              }\n            }\n        })\n        .state(\'root.home\',{\n            views:{\n              \'main@\':{\n                templateUrl:\'main.html\'\n              },\n            }          \n        })\n        .state(\'root.artist\',{\n            views:{\n              \'header@\':{\n                templateUrl:\'artist-header.html\'\n              },\n              \'main@\':{\n                templateUrl:\'artist-main.html\'\n              },\n            }          \n        })\n        .state(\'root.band\',{\n            views:{\n              \'main@\':{\n                templateUrl:\'band-main.html\'\n              },\n            }          \n        })\n
Run Code Online (Sandbox Code Playgroud)\n