angular : duplicate in calling controller's function - angularjs

I have following angular code
<!DOCTYPE html>
<html>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
Test : {{mytest()}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name= "John ";
$scope.mytest = function () {
console.log('my test');
return 'something';
};
});
</script>
</body>
</html>
For more detail, please refer to http://plnkr.co/edit/UIu50AOLMwKIJnAphIB5
Problem: when view in Chrome browser 'Inspect Element' console, the function 'my test' is called 3 times! Why ?

Because you've asked angular to do that. This expression
{{mytest()}}
Is in fact instruction:
"angular, do check if the result value of mytest() is not changing. And do that regularly".
And angular is checking that few times, to be sure that it is not changed. And later, in some other digest it will do the same again
so, rather trigger that method once, and let angular to watch the resulting expression, like with a name above
{{name}}

Related

nested ng-app Controller proglem

i want to use ng-app in another ng-app (nested).
and i have controller for each app ,controllers have same name
code is here :
<!DOCTYPE html>
<html>
<head>
<script src="/scripts/angular.js"></script>
<script src="/scripts/Controller1.js"></script>
<script src="scripts/Controller2.js"></script>
</head>
<body ng-app="MasterApp">
<div ng-controller="myController as myCtr">
{{myCtr.testValue}} ---> controler 1
<div ng-app="DetailApp">
<div ng-controller="myController as myCtr">
{{myCtr.testValue}} ----> controller 2
</div>
</div>
</div>
</body>
</html>
Controlle1.js Code :
var MasterApp = angular.module("MasterApp", ["DetailApp"]);
MasterApp.controller("myController", function ()
{
var myCtr = this;
myCtr.testValue = " a value from Master App ";
});
Controller2.js Code :
var DetailApp = angular.module("DetailApp", []);
DetailApp.controller("myController", function ()
{
var myCtr = this;
myCtr.testValue = " a value from Detail App ";
});
now! controller 2 return value of controller 1!
Result :
a value from Master App
a value from Master App
this is my problem, any idea?
Here is what angularjs docs says about, so what you try to do is not possible.
AngularJS applications cannot be nested within each other.
https://docs.angularjs.org/api/ng/directive/ngApp
But some people found a workaround. Check this post
Can I use one ng-app inside another one in AngularJS

How to understand rootScope?

I'm learning angularjs. When I learn scope, I see rootScope. But I don't really understand what it is.
For example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<h1>Family Name {{lastname}} Members:</h1>
<ul>
<li ng-repeat="x in names">{{x}} {{lastname}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $rootScope) {
$scope.names = ["Emil", "Tobias", "Linus"];
$rootScope.lastname = "Refsnes";
});
</script>
</body>
</html>
But I don't understand what's the difference between the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<h1>Family Name {{lastname}} Members:</h1>
<ul>
<li ng-repeat="x in names">{{x}} {{lastname}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = ["Emil", "Tobias", "Linus"];
$scope.lastname = "Refsnes";
});
</script>
</body>
</html>
So if there is no difference between scope and rootScope, why do we need to use rootScope?
I hope someone can give me a simple example so that I can understand rootScope easily.
I would like to add to #Yaser answer. I will use google chrome console to explain the $rootScope hierarchy which is inherited by all the scopes in the entire web page.
Step 1: Open chrome web developer tool and select the div with ng-app = "myApp"
Step 2: Goto chrome web developer tool's console and type angular.element($0).scope(), this will fetch you an object containing $rootScope details.
Here you will find a property lastname: "Refsnes"
Step 3: Goto Elements tab and select one of the <li>
Step 4: Type angular.element($0).scope() in the console, this will fetch you and object containing selected scope's details
Expand the parent property and you will find rootScope's property lastname: "Refsnes"
This should explain how $rootScope is inherited by all other scopes on the web page
Every application has a single root scope. All other scopes are descendant scopes of the root scope. Scopes provide separation between the model and the view, via a mechanism for watching the model for changes. They also provide event emission/broadcast and subscription facility.
More info here.
However a very simple explanation is consider rootScope and the original parent of all child scopes. If you imagine a hierarchy the rootScope is at the top.
I case of your example there is no rootScope involved, it is just a perent scope.
So you have a lastname in your parent scope, and since ng-repeat creates a child scope, everyone of them has a lastname as well.
The $rootScope is the top-most scope. An app can have only one $rootScope which will be shared among all the components of an app. Hence it acts like a global variable. All other $scopes are children of the $rootScope.
var app = angular.module('myApp', []);
app.controller('Ctrl1', ['$scope','$rootScope', function ($scope,$rootScope) {
$rootScope.name = "Rahul";
}]);
app.controller('Ctrl2', ['$scope','$rootScope', function ($scope,$rootScope) {
$scope.name = $rootScope.name;
}]);
<!DOCTYPE html>
<html lang="en-US" ng-app="myApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div>
<div ng-controller="Ctrl1">
<span>{{name}}</span> - controller -1
</div>
<hr>
<div ng-controller="Ctrl2">
<span>{{name}}</span> - controller -2
</div>
</div>
</body>
</html>
var app = angular.module('myApp',[]) [enter image description here][1] //Here rootScope is created only one time
Check structure from the link: - https://i.stack.imgur.com/rzBj3.png
Here is a simple use of rootScope as passing data from one controlleer to another

Angular js , simple app not working

So , my website is working on paging , and its done by doing .load to div , i am not using angular JS to load child pages , I just want to use angular in my child pages.
This is my child page
<script type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div data-ng-app="myApp">
<div data-ng-controller="appCtrl">
<p>{{greeting.text}}, world </p>
</div>
</div>
<script>
$(document).ready(function () {
var appname = angular.module('myApp', []);
appname.controller('appCtrl', ['$scope',
function ($scope) {
$scope.greeting = { text: 'Hello' };
}]);
})
</script>
Its loaded to masterPage/Index but angular JS is not working , it doesnt do anything , Am i doing it wrong ?
If i load page its self , without index , application is working ,but with index it doesnt
I am getting this console output message : UPDATE putting body instead of div removed this console output , but still my app is not working. And yet again my whole paging sistem wont work if i have body in it , it removes it when loads page so jeah
Uncaught Error: Unknown provider: $controllerProvider from myApp
You haven't declared an app name:
<div data-ng-app>
should be
<div data-ng-app="myApp">
And then in your code you can do:
angular.module('myApp', []);
You were using jQuery to wait for the document ready event, but jQuery hasnt been included.
Also you don't need the data prefix on app and controller.
Try this:
<script type="text/javascript"
src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="appCtrl">
<p>{{greeting.text}}, world </p>
</div>
</div>
<script>
var appname = angular.module('myApp', []);
appname.controller('appCtrl', ['$scope',
function ($scope) {
$scope.greeting = { text: 'Hello' };
}]);
</script>

Angular expression not updated upon button press

I can successfully update an Angular expression immediately but it fails upon a button press. I need a little help here.
Here's the code.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<div ng-app="MyApp">
<div ng-controller="MyController">
<button id="myButton">Press</button>
{{myMessage}}
<script>
function setMessage(msg) {
angular.module('MyApp', [])
.controller('MyController', function($scope) {
$scope.myMessage = msg;
});
}
setMessage("first");
$(document).ready(function() {
$('#myButton').on('click', function( event ){
setMessage("second");
});
});
</script>
</div>
</div>
</body>
</html>
The first call which happens right away correctly updates the expression to "first". However the second call when the button is pressed fails to upate the expression to "second". What am I doing wrong?
First of all, good advice: remove jQuery from the project until you understand well why you should not use jQuery-style development with Angular app. Shortly, Angular has a specific event/parsing/compiling lifecycle that is not the same as just the flow we are used in jQuery projects. Take a look at this thread.
Then what you need to do is to use ngClick directive:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyController">
<button ng-click="setMessage('second')">Press</button>
{{myMessage}}
</div>
</div>
<script>
angular.module('MyApp', [])
.controller('MyController', function($scope) {
$scope.myMessage = 'first';
$scope.setMessage = function(msg) {
$scope.myMessage = msg;
};
});
</script>
Remove the function around your angular module and you should use angular's ng-click directive to update your html on click:
<div ng-app="MyApp">
<div ng-controller="MyController">
<button id="myButton" ng-click="update('second')">Press</button>
{{myMessage}}
<script>
angular.module('MyApp', [])
.controller('MyController', function($scope) {
$scope.myMessage = "first";
$scope.update = function(msg){
$scope.myMessage = msg;
}
});
</script>
</div>
</div>
The documentation for ng-click: https://docs.angularjs.org/api/ng/directive/ngClick
Don't mix jQuery with angularjs, unless is totally needed. See this answer about it
you should use all the events, functions and directives providad by angularjs.
So your coude would look to something like this
<div ng-app="MyApp">
<div ng-controller="MyController">
<button ng-click="setMessage()">Press</button>
{{myMessage}}
<script>
function setMessage(msg) {
angular.module('MyApp', [])
.controller('MyController', function($scope) {
// set the original value for myMessage
$scope.myMessage = "first";
// update with second value
$scope.setMessage = function(){
$scope.myMessage = "second";
}
});
}
</script>
</div>
</div>
Of course you should organize this better, but this is the first approach
The main difference is that if you use the angular events (like ng-click in this case) it will let Angular knows what something has changed and that it has to update/refresh the view.
If you change something with jQuery, unless you force angular to know it (using $scope.$apply()) there is no way that angular knows by itself that the model has changed.

Why does $digest() crash

In the following AngularJS code:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js" ></script>
</head>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('MainCtrl', ['$scope', '$rootScope', function ($scope, $rootScope)
{
// let's assume that scope was dependency injected as the $rootScope
var scope = $rootScope;
scope.name = 'misko';
scope.counter = 0;
scope.$watch('name', function(newValue, oldValue)
{
scope.counter = scope.counter + 1;
});
scope.$digest();
}]);
</script>
<body>
<div ng-app="myApp">
<div ng-controller="MainCtrl">
<div id="divCool" ng-show="false">Cool</div>
</div>
</div>
</body>
</html>
scope.$digest(); crashes but I don't know why. I took the code inside the controller straight from angularjs.org
There is no reason for calling digest in that context. Angular manages that for you. Actually, you hardly ever are going to need to use that function, but most commonly apply.
In this case, the code is taken from angular docs in a context of unit testing, where the scope needs to be refreshed by yourself for the assertions after setting up the test conditions.

Resources