3

Here's the code snippet of the Angular js app.

var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
  $scope.get = function() {
    $scope.thiss = false;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
  <p ng-controller="myctrl">
    <button ng-click="get()">Click</button>
    <p ng-show="thiss">This is it</p>
  </p>
</div>

i have been learning AngularJS. I cannot understand why this simple example fails to work. I have been followng w3cschools tutorial and the syntax seem to perfect align with it. Is it something to with scoping ? or do i have to bind ng-show with model data.

I also did the following but it doesnot seem to work.

<div ng-app="list" ng-init="thiss = true">
     <p ng-controller="myctrl" >
     <button ng-click="thiss=false">Click</button>
    <p ng-show="thiss"> This is it</p>
     </p>
</div>

Why is placing the controller on the div tag works ? But fails to work when it is in the child element?

Sohil
  • 532
  • 7
  • 26

6 Answers6

2

It does not work because you have a <p> tag within a <p> tag. It should work if you change you code as follows.

<div ng-controller="myctrl" >
    <button ng-click="thiss=false">Click</button>
    <p ng-show="thiss"> This is it</p>
</div>

var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
  $scope.get = function() {
    $scope.thiss = false;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
  <div ng-controller="myctrl">
    <button ng-click="get()">Click</button>
    <p ng-show="thiss">This is it</p>
  </div>
</div>

Check out Why <p> tag can't contain <div> tag inside it? for the reason why <p> cannot include block level elements

Community
  • 1
  • 1
Parthasarathy
  • 2,698
  • 1
  • 12
  • 14
1

Try following code.

var app=angular.module("list",[]);
  app.controller("myctrl",function($scope){
  $scope.get=function(){
       $scope.thiss = false;
     }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-controller="myctrl">
  <p ng-init="thiss=true">
    <button ng-click="get()">Click</button>
    {{thiss}}
    <p ng-show="thiss">Show Content</p>
    <p ng-show="!thiss">Hidden Content</p>
  </p>
</div>
Mohit Tanwani
  • 6,608
  • 2
  • 14
  • 32
  • The code worked but my question is why didnt it worked on the first place? Am i missing out any important concept? – Sohil Aug 24 '16 at 09:56
  • @Sohil: You need to use ng-model to consider it as a scope variable or scope variable needs to be called defined as object reference. – Mohit Tanwani Aug 24 '16 at 10:00
  • @Sohil : I've edited my answers, it shows if you put ng-app and ng-controller on same elements then it's working – Mohit Tanwani Aug 24 '16 at 10:32
  • Thanks for taking time to answer. But writing both ng-controller and ng-app on the same div tag restrict of having multiple controller? – Sohil Aug 24 '16 at 11:06
  • @Sohil: I am still finding the reason why this happens with your code, but if my code helps you then mark it. – Mohit Tanwani Aug 24 '16 at 11:37
  • I have upvoted it but it hasnt answered the question about the behaviour. – Sohil Aug 24 '16 at 11:46
1

Try this. I have just remove ng-controller from <p> and put it inside div with ng-app. don't know the reason behind this behavior of angularjs but it works as you want.

var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
  $scope.get = function() {
    $scope.thiss = false;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true" ng-controller="myctrl">
  <p>
    <button ng-click="get()">Click</button>
    <p ng-show="thiss">This is it</p>
  </p>
</div>
Krupesh Kotecha
  • 2,396
  • 3
  • 21
  • 40
1

Please, don't try to make your HTML standard, follow some rule defined by HTML. Don't put nested <p> tags. AngularJS sometimes don't work for invalid DOM. I used <span> tag instead of nested <p> works fine.

var app = angular.module("list", []);
app.controller("myctrl", function($scope) {

  $scope.get = function() {
    $scope.thiss = false;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
  <p ng-controller="myctrl">
    <button ng-click="get()">Click</button>
    <span ng-show="thiss">This is it</span>
  </p>
</div>

For more information validate HTML. Please, check following HTML code at: https://validator.w3.org/#validate_by_input

<!doctype html>
<html>
<head>
<title>Test</title>
</head>
<body>
<p>
<p>
</p>
</p>
</body>

</html>
Bhuwan Prasad Upadhyay
  • 2,916
  • 1
  • 29
  • 33
0

try after removing the blank array from the dependency

var app = angular.module('list');

make sure that the controller should be placed in <div ng-controller="myctrl">

md-5h04I3
  • 214
  • 2
  • 12
0

Your code:

 <p ng-controller="myctrl">
    <button ng-click="get()">Click</button>
    <p ng-show="thiss">This is it</p>
    </p>

this is how a browser interprets html according to DOM :

    <p ng-controller="myctrl">
     <button ng-click="get()">Click</button>
   </p>
   <p ng-show="thiss">This is it</p>
   <p></p>

therefore the scope of your controller "myctrl" does not apply on nested para, try using div instead of nested <p>

var app = angular.module("list", []);
app.controller("myctrl", function($scope) {
  $scope.get = function() {
    $scope.thiss = false;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="list" ng-init="thiss = true">
  <div ng-controller="myctrl">
    <button ng-click="get()">Click</button>
    <p ng-show="thiss">This is it</p>
  </div>
</div>