How to understand rootScope? - angularjs

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

Related

AngularJS singleton service setting the value

I am new to angularJS and I was going through the AngularJS services tutorial.
I understood that Services are Singleton in AngularJS. Now my intention is
I will set a value to Service and that value should be able to access anywhere.
I created a service in one page and set the value from one Controller.
Now I accessed this service in anotherpage. I am getting the below error.
Uncaught Error: [$injector:modulerr]
I tried the below code.
page1.html
<html>
<head>
<title>Angular JS Services</title>
<script
src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<h2>AngularJS Services</h2>
<div ng-app="myApp">
<div ng-controller="FirstCtrl">
Set name: <input type="text" ng-model="test">
<!-- <button ng-click="next('page2.html')">next</button> -->
<button ng-click="next()">Set the value</button>
</div>
<div ng-controller="SecondCtrl">
<button ng-click="next()">Go to next page</button>
</div>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.service('HelloService', function() {
var value ='';
this.setValue = function(a) {
value = a ;
};
this.getValue= function(){
return value ;
}
});
myApp.controller('FirstCtrl', function($scope, HelloService) {
$scope.next= function() {
alert("Value "+$scope.test);
HelloService.setValue($scope.test);
$scope.answer = HelloService.getValue();
alert($scope.answer);
}
});
myApp.controller('SecondCtrl', function($scope, HelloService,$window) {
$scope.next= function() {
$scope.newvalue = HelloService.getValue();
alert($scope.newvalue);
$window.location.href = 'page2.html';
}
});
</script>
</body>
</html>
page2.html
<html>
<head>
<title>Angular JS Services</title>
<script
src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<h2>AngularJS Service test</h2>
<div ng-app="myApp">
<div ng-controller="SecondCtrl">
<button ng-click="retrieve()">Retrieve the value</button>
</div>
</div>
<script>
var myApp = angular.module('myApp', ['HelloService']);
myApp.controller('SecondCtrl', function($scope, HelloService) {
$scope.retrieve= function() {
alert("2nd page");
$scope.newvalue = HelloService.getValue();
alert($scope.newvalue);
}
});
</script>
</body>
</html>
Angular is a single page applications framework, your two pages are two different angular applications and services (and other resources) can't be shared between them.
You can create a multi-view application using routes. please check angular tutorials
When the page reloads, e.g., from page1 to page2, everything resets. The singleton value will persist if you inject it into controllers in the current page-load. The most common way to do this is to use ng-view / Routing. In that instance, you'd create a skeleton page of html, body, etc, and remove the content that's different between page1 and page2. Put those differences into .html "partial" files and then use ng-view / Routing to load each partial based on URL state and it'll use the same service singleton.
https://docs.angularjs.org/api/ngRoute/directive/ngView
Angular service is just javascript object. It is stored inside angular as well as your module, controllers, directives etc.
In simple case your application is "single page" (however may be quite reach), which means that you have i.e. index.html, where you include angular.js and your custom components.
When people talk about views and pages in angular, they usually mean 'part of page', not real 'pages' like index.html/#home, index.html/#view1, ... (this urls may look like /home, /view1 in html5 mode) -- however if you inspect html source of any such page you will see that it is the same.
You can say that angular singleton is an object that is created once per angular load.
When you change real browser page, browser will discard all js objects: angular itself as well as your factories, etc.
If you just use a value to share across your app, you should use a type service value:
angular.module('myValue')
.value('myShareValue', 123);
and then inject into your module app and controller.
myApp = angular.module('myApp', ['myValue']);
myApp.controller('myController', [
'$scope', 'myShareValue',
function($scope, myShareValue){
$scope.valueShare = myShareValue;
}
]);
You can read this slides in spanish and see the differences between types of services angular. Also this video

rootScope is not working to bind data from controller to view

i m new in angularjs. But there is problem that i cant resolve it my code is below
My index.html file is given below
<!doctype html>
<html ng-app = "myApp">
<head>
<script src=""https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js""></script>
<script>
var app = angular.module('myApp', []);
app.run(function($rootScope){
$rootScope.name = "Ari Lerner";
});
</script>
</head>
<body>
<div>
{{name}}
</div>
</body>
</html>
But still the output on Browser in
{{name}}
please help to solve my problem
I think you made this pretty complex for your self. You need to play with the scope of that moment instead of using the rootScope when their is only one level of scope involved.
However in order to make your example work created a fiddle for the same:
Fiddle
Code Snippet:
HTML:
<div ng-app>
<div ng-controller="test">
{{name}}
</div>
</div>
JS:
function test($scope){
$scope.name = "Ari Lerner";
}
Make sure your angularjs is included properly:
Put double quotes only once:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
demo: jsfiddle

Can I bind an AngularJS model to a hash URL and an HTML input at the same time?

I'm teaching myself Angular and I've looked over a number of examples that show how to bind a model to an HTML input so that they always contain the same text.
I understand that Angular also provides the $location service which works with the URL.
I have an application that I'm thinking of partially rewriting in Angular as a learning example.
In my example, I have an HTML input that I keep synced up with a model using jQuery and also synced up with a hash URL.
Is there a simple way of accomplishing this with AngularJS?
Consider the example application bellow:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/angular.js"></script>
<script>
var myApp = angular.module('myApp', []);
function FirstController($scope, $location) {
var data = {
bar: 'hello world'
};
$scope.data = data
}
</script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="FirstController">
<input ng-model="data.bar" />
<h2>{{ data.bar }}</h2>
</div>
</div>
</body>
</html>
This is a simple example showing how the model can be kept synced with a textbox. I was wondering if it's possible to keep it synced with a hash URL, as well, so that we would have http://www.example.com#bar=What_The_User_Typed
What you probably need is the $routeProvider
https://docs.angularjs.org/tutorial/step_07

AngularJS same controller in non nested divs

I have got two separate divs as shown in the code below. What I am trying to do is update the Controller from first div and then detect the changes in the second div using the same controller. When I press the button, 'i am here' gets printed on the console but the data in 2nd div won't update. It should change to "clicked".
<html ng-app="app">
<head>
<title></title>
</head>
<body>
<h1>Divs below should not be nested</h1>
<div id="notNested1" ng-controller="Controller1">
<button ng-click="buttonClick()">Click me</button>
</div>
<div id="notNested2" ng-controller="Controller1">
<p>{{paragraph}}</p>
</div>
<script type="text/javascript" src="libs/angular/angular.js"></script>
<script>
var app = angular.module('app', []);
function Controller1($scope) {
$scope.paragraph = 'initial';
$scope.buttonClick = function () {
console.log('i am here');
$scope.paragraph = "clicked";
};
}
</script>
</body>
</html>
How can I fix this problem? Also what is the problem here? Is it because the $scope is different for both divs?
Thanks
You should probably share the data using a service/factory.
You could also create a parent controller with the data there, and reference it from the child controllers, but a shared service seems better.
Yes you have 2 separate scopes, so they do not interact with each other.

Can I modify external statment on my template?

My website follow the following template:
<html lang="fr" ng-app="myApp">
<head>
<meta charset="UTF-8"><title>{{title}}</title>
</head>
<body>
<navbar>
// My menu and other links
</navbar>
<section role="main" ng-controller="car-controller">
<ul>
<li ng-repeat="car in car">
{{car.state}}
</li>
</ul>
</section>
// Footer
</body>
</html>
All my different pages should have a different main section with a different controller to manage them.
My question is : how can I update my {{title}} statment from all my controllers like the car-controller on this exemple?
You can modify the document title from inside the controllers by injecting $window or $document, without binding any value to it.
angular.module('myApp')
.controller('car-controller', function($scope, $window){
$window.document.title = "Title from Car Controller";
});
You can move the logic to a callable function if required and this can be done for all the controllers you are planning to use for each section.

Resources