Невозможно получить доступ к свойству $scope за пределами контроллера AngularJS в функции анимации

enter image description here

angular.module("modalApp", ['ngAnimate', "ngMaterial", "ngMessages"])
    .controller('modalCtrl', function ($scope) {
		$scope.direction = 'left';
        $scope.currentIndex = 0;
		$scope.init = true;
		$scope.initWizard = function() {
			if($scope.init) {	
				$scope.setCurrentIndex(0);	
			}	
			$scope.init = false;		
		}

        $scope.setCurrentIndex = function (index) {
            $scope.currentIndex = index;
        }
		
        $scope.isCurrentIndex = function (index) {
            return $scope.currentIndex === index;
        }

        $scope.nextModalStep = function () {
            $scope.direction = 'left';
            if($scope.currentIndex < $scope.modalSteps.length - 1) {
				++$scope.currentIndex;
			} 
        }

        $scope.prevModalStep = function () {
            $scope.direction = 'right';
            if($scope.currentIndex > 0) {
				--$scope.currentIndex;
			} 
        }
    })
    .animation('.modalViewAnimation', function () {
        return {
			beforeAddClass: function(element, className, done) {
				var scope = element.scope();
				if (className == 'ng-hide') {
					var elementWidth = element.parent().width();
					startPoint = 0;
					if(scope.direction !== "right") {
						finishPoint = elementWidth;
					} else {
						finishPoint = -elementWidth;
					}
					TweenMax.fromTo(element, 0.5, { left: startPoint}, {x: finishPoint, onComplete: done });
				} else {
					done();
				}
			},
			removeClass: function(element, className, done) {
				var scope = element.scope();
				if (className == 'ng-hide') {
					var elementWidth = element.parent().width();
					finishPoint = 0;
					if(scope.direction !== "right") {
						startPoint = elementWidth;
					} else {
						startPoint = -elementWidth;
					}
					TweenMax.to("section", 0.5, { height: element.outerHeight()});
					TweenMax.fromTo(element, 0.5, { x: startPoint}, {x: finishPoint, onComplete: done, delay:0.25});
				} else {
					done();
				}
			}
        }
	});

У меня есть слайдер мастера, который почти работает. Моя проблема заключается в доступе к свойству направления в моей функции анимации после того, как оно было установлено в контроллере. Объект области имеет значение внутри анимации, но точечная нотация получения свойства направления с помощью «scope.direction» возвращает неопределенное значение. Почему? Любая помощь очень ценится. Стоит отметить, что я немного изменил функцию анимации с этого https://github.com/simpulton/angular-photo-slider для достижения того, чего я хочу. Я не понимаю, почему мой scope.direction возвращает значение undefined?


person John Stafford    schedule 06.03.2016    source источник
comment
Я добавил var перед переменными finishPoint и startPoint, думая, что это может повлиять на вещи, но все еще не определено.   -  person John Stafford    schedule 06.03.2016
comment
интересная находка только сейчас. свойство direction находится в переменной области видимости в моей функции анимации (см. скриншот моего отладчика Chrome в строке if(scope.direction !== right) { Как мне получить к этому доступ?   -  person John Stafford    schedule 06.03.2016
comment
красная стрелка и прямоугольник на снимке экрана выше — это не та строка, которая предоставляет отладочную информацию, которую вы видите (это плохо). Это из строки if(scope.direction !== right) { в функции анимации. Свойство direction определенно находится в переменной области видимости в дочернем элементе. Я просто не знаю, как получить к нему доступ.   -  person John Stafford    schedule 06.03.2016
comment
хорошо. нашел это. scope.$$childHead.direction обращается к переменной, но почему я должен обращаться к ней из $$childHead, а не из корневой области?   -  person John Stafford    schedule 06.03.2016


Ответы (1)


Не уверен в причине, но мне пришлось получить ее от childHead. Ключом для меня было внедрение rootScope. Рабочий пример: JSFiddle (отредактировано для "приведения в порядок" моего кода ;-))

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

myApp.controller('myCtrl', function($scope) {
  $scope.onOff = false;
});

myApp.animation('.fold-animation-expand', ['$animateCss', '$rootScope',
  function($animateCss, $rootScope) {
    return {
      enter: function(element, doneFn) {
        console.log("onOff:" + $rootScope.$$childHead.onOff);
        return $animateCss(element, {
          from: {
            "font-size": '0px'
          },
          to: {
            "font-size": '20px'
          },
          duration: 2
        });
      }
    }
  }
]);
.box {
  height: 100px;
  width: 100px;
  background-color: blue;
  color: white;
  float: left;
}
.box.ng-enter {
  transition: 2s linear all;
  opacity: 0;
}
.box.ng-enter.ng-enter-active {
  opacity: 1;
}
<html ng-app="myApp">

<head>
  <script src="http://code.jquery.com/jquery-2.2.1.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
  <script src="https://code.angularjs.org/1.5.0/angular-animate.js"></script>
</head>

<body>
  <div ng-controller='myCtrl'>
    onOff state:{{onOff}}
    <br>
    <br>
    <button ng-click="onOff?onOff=false:onOff=true">Run animation</button>
    <hr>

    <div ng-if="onOff == true" class="fold-animation-expand" style="font-size:0px">
      Expanding element
    </div>

    <hr>Example of CSS-based transition
    <br>
    <div ng-if="onOff" class="box">Animated Box</div>

  </div>
</body>

</html>

person Loren    schedule 06.03.2016
comment
Спасибо за ваш вклад, Лорен. Я ценю его. Первый раз копаюсь в отладчике с прицелом. - person John Stafford; 06.03.2016