1

I have ng-if conditions in two levels. if the first condition in the first div satisfy the second div should be displayed. Similarly, if the second ng-if satisfies the third div should be displayed. But I can able to see only the second div.

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div><input type="number" ng-model="temp"></div>
<div ng-if="temp>40">
  <input type="radio" ng-click="temp2=true">Yes
  <input type="radio" ng-click="temp2=false">No
</div>
<div ng-if="temp2">
  <p>Some content</p>
</div>

The last div displays if I use ng-show. But I must not use ng-show. There are some more divs which work based on these conditions. Please help me in this regard

Vivz
  • 6,625
  • 2
  • 17
  • 33
Naresh
  • 108
  • 1
  • 7

3 Answers3

5

Because the ng-if create new scope. Try this one.

  <div><input type="number" ng-model="temp"></div>
   <div ng-if="temp>40">
      <input type="radio" ng-click="temp2=true">Yes
      <input type="radio" ng-click="temp2=false">No
       <div ng-if="temp2">
         <p>Some content</p>
      </div>
   </div>

Edit

It's better use controllerAs syntax.

var app = angular.module('myApp', []);
app.controller('AppCtrl', function($scope) {
  var vm = this;
  
  
  vm.setTemp2 = function(){
    vm.temp > 40 && vm.temp2 ?  vm.temp2= true : vm.temp2=false;
  }
  
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div ng-app="myApp" ng-controller="AppCtrl as vm">
  <div><input type="number" ng-model="vm.temp" ng-change="vm.setTemp2(vm.temp)" ></div>
  <div ng-if="vm.temp>40">
    <input type="radio" name="content" ng-click="vm.temp2=true">Yes
    <input type="radio" name="content" ng-click="vm.temp2=false">No
  </div>
  <div ng-if="vm.temp2">
    <p>Some content</p>
  </div>
</div>
Hadi J
  • 16,989
  • 4
  • 36
  • 62
  • Hi, sorry to say this. Your code is not working. Try this, enter a value which is greater than 40 into the input field. Now you can check the Yes radio button. So that you can able to see "Some content". Now delete the number in the input field. Still, you can see the "Some content". But It should also be removed from the dom as the radio is not in the dom tree. The code is generated dynamically using JS and appended to html content. So please think, without taking the help from controller. Thanks in advance. – Naresh Jul 29 '17 at 06:42
  • Thanks a lot. Your code is working partially. For the "Some content" div you should not use temp>40. Because the code is generated dynamically in a javascript. while generating the last div I have only second level condition. Not the first one. Please try the same code by removing the temp>40. And also the first div should be closed after input field.Because all the divs are generated within a loop. So, when the iteration completes the div must be closed. Please ignore if I am wrong – Naresh Jul 29 '17 at 07:38
0

This is because ng-if creates a new child scope. This can be avoided by binding the property to an object. By using ., the property will be directly binded to the parent and not the child scope which is created in ng-if. You don't have to restructure all the divs.

   var myApp = angular.module('myApp', []);
    myApp.controller('ctrl', ['$scope', function ($scope) {
     $scope.temp2={};
    }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<body ng-app="myApp" ng-controller="ctrl">
<div ><input type="number" ng-model="temp"></div>
<div ng-if="temp>40">
<input type="radio"  ng-click="temp2.val=true">Yes
<input type="radio"  ng-click="temp2.val=false">No
</div>
<div ng-if="temp2.val&&temp>40">
<p>Some content</p>
</div>
</body>

For more Info : What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

This can also be avoided by using controllerAs syntax as mentioned by @Hadi. controllerAs syntax will take care of the dot rule.

Vivz
  • 6,625
  • 2
  • 17
  • 33
  • 1
    `controllerAs` implicitly take care of `Dot Rule`, so `controllerAs` is more preferred this days IMO – Pankaj Parkar Jul 29 '17 at 06:08
  • I agree that it will take care of the dot rule. But I was explaining the cause of the problem and how that can be avoided by using dot. I was explaining so that the OP understands what is happening. I wanted him to know the basics of javascript prototypical inheritance and then he can move onto controllerAs syntax – Vivz Jul 29 '17 at 06:17
  • @Vivz. I know the dot concept. And I am using the dot concept in my coding. But here posted the question without dots. I am so sorry about this. – Naresh Jul 29 '17 at 06:32
  • But you can use the same concept to avoid the problem is what I meant – Vivz Jul 29 '17 at 06:39
  • @Vivz, Thanks a lot. Your code is working partially. For the "Some content" div you should not use temp>40. Because the code is generated dynamically in a javascript. while generating the last div I have only second level condition. Not the first one. Please try the same code by removing the temp>40. And also the first div should be closed after input field.Because all the divs are generated within a loop. So, when the iteration completes the div must be closed. Please ignore if I am wrong. – Naresh Jul 29 '17 at 07:27
0

No need to use ng-click, you can just bind the value of radio button with the model using ng-model.

There are actually two problems:

  1. The ng-if create a new scope. So you need to put your second ng-if code inside the parent ng-if.
  2. And you did not give the name property to your radio button which is necessary.

Updated Code:

Just replace your code with the below one..

<div ng-app="">    
  <div><input type="number" ng-model="temp"></div>
  <div ng-if="temp>40">
    <input type="radio" name="content" ng-model="temp2" value="true">Yes
    <input type="radio" name="content" ng-model="temp2" value="false">No
    <div ng-if="temp2=='true'">
      <p>Some content</p>
    </div>
  </div>
</div>
Surjeet Bhadauriya
  • 6,755
  • 3
  • 34
  • 52