How to get nested ng-if triggering?

558 Views Asked by At

If I have a ng-if inside an ng-if, the inner ng-if won't initiate if the condition on the outer ng-if is in the process of hiding.

I'd like the embedded ng-if to trigger even if the outer one is in the process of hiding. In this particular case I have a long transition so things going on in the item can still be seen.

Clicking toggle should show "goodbye" but since the outer div is in the process of being removed, the inner content isn't updated.

https://plnkr.co/edit/0MT62ZNJ8rsLtnhhryfk?p=preview

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

app.controller('HomeController', ['$scope', function(scope) {
  scope.data = {
    show: true,
    show2: true,
  };
  scope.toggle = function() {
    scope.data.show = !scope.data.show;
    scope.data.show2 = !scope.data.show2;
  };
}]);
div {
  padding: 20px;
  border: 1px solid black;
}

.out {
  transition: 4s;
}

.out.ng-leave {
  background: red;
}

.out.ng-leave-active {
  background: purple;
}

.out.ng-enter {
  background: yellow;
}

.out.ng-enter-active {
  background: green;
}

.as-console {
display: none !important;
}
<!doctype html>
<html ng-app="App">

<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular-animate.min.js"></script>

</head>

<body ng-controller="HomeController">

  <div class="out" ng-if="data.show" ng-animate-children>
    <div class="inA" ng-if="data.show">
      HELLO
    </div>
    <div class="inB" ng-if="!data.show">
      GOODBYE
    </div>
  </div>

  <div ng-click="toggle()">toggle</div>

</body>

</html>

1

There are 1 best solutions below

1
On

Change one of the variables using $timeout, so the content will be updated before the parent div element starts the animation:

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

app.controller('HomeController', ['$scope', '$timeout', function(scope, $timeout) {
  scope.data = {
    show: true,
    show2: true,
  };
  scope.toggle = function() {
    $timeout(function(){  scope.data.show = !scope.data.show; });
    scope.data.show2 = !scope.data.show2;
  };
}]);
div {
  padding: 20px;
  border: 1px solid black;
}

.out {
  transition: 4s;
}

.out.ng-leave {
  background: red;
}

.out.ng-leave-active {
  background: purple;
}

.out.ng-enter {
  background: yellow;
}

.out.ng-enter-active {
  background: green;
}

.as-console {
  display: none !important;
}
<!doctype html>
<html ng-app="App">

<head>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular-animate.min.js"></script>

</head>

<body ng-controller="HomeController">

  <div class="out" ng-if="data.show" ng-animate-children>
    <div class="inA" ng-if="data.show2">
      HELLO
    </div>
    <div class="inB" ng-if="!data.show2">
      GOODBYE
    </div>
  </div>

  <div ng-click="toggle()">toggle</div>

</body>

</html>