повторить анимацию полный обратный вызов

0

Итак, у меня есть простой ng-repeat с анимацией ввода, определенной в javascript.

Песочница: http://codepen.io/anri82/pen/KwgGeY

код:

<div ng-app="myApp" ng-controller="MyController">
  {{state}}
  <ul>
     <li class="repeat-animate" ng-repeat="item in list">{{item}}</li>
  </ul>
  <button ng-click="add()">add</button>
</div>

angular.module('myApp', ['ngAnimate'])
.controller("MyController", function($scope) { 
   $scope.state ="idle";
   $scope.id=3;
   $scope.list = [1,2];
   $scope.add = function () {
     $scope.state="pushing";
     $scope.list.push($scope.id++);
     $scope.state="done pushing";
   }; 
}).animation('.repeat-animate', function () {
  return {
    enter: function (element, done) {
      element.hide().show(2000, done);
    }
  };
});

Как переключить $scope.state в done pushing только после завершения анимации? Ответ должен быть в angular, не предлагайте setTimeout.

Теги:
ng-animate

1 ответ

2
Лучший ответ

С помощью подхода javascript-анимации, который вы делаете, вам нужно овладеть областью текущего элемента в обработанном анимацией обратном вызове. Поскольку после обновления переменной вне контекста angular вам нужно вручную вызвать цикл дайджеста, выполнив $scope.$apply() (или используйте $timeout, scope.$evalAsync и т.д.). А также, поскольку ng-repeat создает дочернюю область, область элемента фактически имеет унаследованное свойство state из области родительского контроллера, поэтому для того, чтобы обновление получило отражение в родительской области, используйте объект для обертывания state, так что оба дочерних объекта и родительского объекта имеют одну и ту же ссылку на объект.

angular.module('myApp', ['ngAnimate'])
.controller("MyController", function($scope) { 
  $scope.push = {state: "idle" }; 
  $scope.id=3;
  $scope.list = [1,2];
  $scope.add = function () {
    $scope.push.state="pushing";
    $scope.list.push($scope.id++);

  }; 
}).animation('.repeat-animate', function () {
  return {
    enter: function (element, done) {
     element.hide().show(2000, function(){
          var scope = element.scope(); //Get the scope
          scope.$evalAsync(function(){ //Push it to async queue
             scope.push.state="done pushing"
          }); 
      });
    }
  };
});

Демо

  • 0
    $ evalAsync должен принимать строку, нет? Прямо сейчас ваш код выполняет присваивание и передает "done pushing" scope.$evalAsync "done pushing" в scope.$evalAsync , что ничем не отличается от выполнения scope.push.state="done pushing"; scope.$evalAsync();
  • 0
    @ FabrícioMatté Конечно, нет разницы, он просто написан в одну строку, он может принимать любое выражение . а тут просто не важно
Показать ещё 9 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню