使用AngularJS访问.animation中的$ scope

时间:2015-08-28 13:21:59

标签: javascript angularjs angularjs-scope ng-animate

我有一个可调整的幻灯片指令(自制) - 一些变量会发生变化,例如,我有一个包含这些设置的范围变量:

{
 animationSpeed : 30,
 transitionTime : 1.5
}

作为动画库我使用greensock(GSAP),动画定义如下:

ModuleSlideshow.animation('.slide-left-animation', ['$window',function ($window) {
    "use strict";

    var getScope = function(e){
        var scope = angular.element(e).scope();
        if(scope){ scope = scope.$parent; }
        if(scope){ scope = scope.$parent; }
        return scope;
    };

    return {
        enter: function (element, done) {
            TweenMax.fromTo(element, getScope(element).animationSpeed, {left: -$window.innerWidth, ease : Power4.easeInOut}, {left: 0, ease: Power4.easeInOut, onComplete: done});
        },

        leave: function (element, done) {
            TweenMax.to(element,getScope(element).animationSpeed,{left : $window.innerWidth,ease : Power4.easeInOut, onComplete: done});
        }
    };
}]);

正如你所看到的那样,我尝试用我得到的元素(元素是一个.slide div)来获取范围,然后我去父母两次(以获取正确的变量)。

这有时会有效,但有时却没有,我收到一些JavaScript错误,指出"cannot read property $parent of null"。我试图直接注入$scope,但这似乎不起作用。在我的情况下你会如何访问范围?我应该改变设置动画的方式吗?

2 个答案:

答案 0 :(得分:0)

我遇到了一个几乎和你一样的问题,我需要访问该元素的范围。似乎使用element.scope()会很好,但如果您打算使用$compileProvider.debugInfoEnabled(false);,这会在Angular应用程序中推荐用于提高性能。虽然在关闭“调试信息”时无法访问元素的范围,但您仍然可以通过data()访问元素的控制器。

也许如果您重构代码以使用控制器作为指令,您将能够访问所需的范围变量。

angular.module('myApp')
  .config(['$compileProvider', function ($compileProvider) {
    $compileProvider.debugInfoEnabled(false);
  }])
  .controller('myDirectiveCtrl', function ($scope, $el) {
    this.animationSpeed = $scope.animationSpeed;
  })
  .directive('myDirective', function () {
    return {
      restrict: 'E',
      scope: {
        animationSpeed: '='
      },
      controller: 'myDirectiveCtrl',
      controllerAs: 'vm'
    };
  })
  .animation('.my-directive', function () {
    return {
      addClass: function (element, className, done) {
        var vm = element.data().$myDirectiveController;
        console.log(vm.animationSpeed, className);
      },
      removeClass: function (element, className, done) {
        var vm = element.data().$myDirectiveController;
        console.log(vm.animationSpeed, className);
      }
    }
  })

答案 1 :(得分:0)

我试过上面的那个;我无法将范围注入指令控制器。我创建了一个服务,而不是这样沟通,它运作良好,我可以保留它们。

angular
        .module('App')
        .service('SliderService', function (){
            return {
                direction: null
            };
        });
     angular
        .module("App")
        .directive('slider',slider);

     slider.$inject = ['SliderService'];

        link: function (scope, elem, attrs) { var unbindWatch =  scope.$watch('direction', function () { SliderService.direction = scope.direction }); 

记得用范围杀死手表和计时器。

scope.$on('destroy',function () { unbindWatch() }) }

然后对于动画使用以下

angular
    .module("App")
    .animation('.slide-animation', slideAnimation);
slideAnimation.$inject  =['SliderService'];
function slideAnimation ( SliderService) {
    return {
        beforeAddClass: function (element, className, done) {
            if (className == 'ng-hide' && SliderService.direction) { ... }
        }
    }