ngView动画输入不在第一页加载时触发

时间:2017-01-10 08:07:21

标签: javascript angularjs ngroute ng-animate

我已经在我的网站上遇到了一个非常微妙的bug几天,但找不到任何解决方案(也许我对AngularJs的了解还不够)

我正在使用最新的角度(v1.6.1),ngRoute和ngAnimate。

当你去网站时(当网站第一次加载时),ngView动画输入没有触发。

这是我的代码:

var app = angular.module('app', ['ngAnimate', 'ngRoute']);

app.animation('.view', function () {
  return {
    enter : function (element, done) {
      alert('enter');
      done();
    },
    leave : function (element, done) {
      alert('leave');
      done();
    }
  }
});

//Config

app.config(function ($routeProvider, $locationProvider, $httpProvider){

  $routeProvider.when('/test.php',{
    template : function () {
      return "<div>Welcome to test page</div>";
    }
  });
  $routeProvider.when('/test.php/:path',{
    template : function () {
      return "<div>Inside page</div>";
    }
  });

  $locationProvider.html5Mode({enabled: true, requireBase: true});
});

我在GitHub上看到过这个问题: https://github.com/angular/angular.js/issues/10536

那说“这是一个功能,而不是一个错误”。但问题是,在生产网站上,它有时会触发,有时甚至不会(特别是在Safari和移动浏览器中)。

例如,当我使模板加载速度变慢时:

$routeProvider.when('/test.php',{
    template : function () {
      return "<div>Welcome to test page</div>";
    },
    resolve: {
      message: function ($timeout, $q) {
        console.log('asdasa')
        return $q(function(resolve){
          $timeout(function () {
            resolve('message');
          },1000);
        });
      }
    }
  });
  $routeProvider.when('/test.php/:path',{
    template : function () {
      return "<div>Inside page</div>";
    },
    resolve: {
      message: function ($timeout, $q) {
        return $q(function(resolve){
          $timeout(function () {
            resolve('message');
          },1000);
        });
      }
    }
  });

或者使用PHP:

sleep(1)

输入事件会触发,但也许当它在缓存中或浏览器快速获取时,它不会。

github上有几个黑客,但由于它们的可靠性,我不是快速黑客的忠实粉丝。

例如,github上提到的这个脏黑客不再起作用了:

$rootElement.data("$$ngAnimateState").running = false;

我也尝试过:

app.run(function($animate) {
  $animate.enabled(true);
});

但它有一种非常奇怪的行为,在野生动物园中它无济于事。

这是JSBIN EXAMPLE

提前致谢,我将等待您的帮助!

1 个答案:

答案 0 :(得分:0)

因此,在对github进行了几天的讨论之后,我们找到了一个解决方案:

首先,我们必须在app.run上启用动画(默认情况下禁用)。然后根据我们的情况,我们应该禁用body上的动画,并直接在视图上启用它。但只要我们不能在[ng-view]元素上启用动画,因为我们无法在$ animate之前获得新创建的节点,我们应该将[ng-view]元素包装在容器div中。

HTML:

<div id="view-container">
   <div class="view" ng-view></div>
</div>

JS:

app.run(function($animate) {
  $animate.enabled(true);
  $animate.enabled(document.body, false);
  $animate.enabled(document.getElementById('view-container'), true);
});

但这还不够,因为角度检查document.hidden而且确实如此,$ animation不起作用。因此我们必须覆盖角度函数,以便$动画始终有效(尽管对于动画平滑度可能有点危险):

app.value('$$isDocumentHidden', function() { return false; });

就是这样!希望有人会觉得它很有用!