How to change $rootScope value in an ng-click function? - javascript

I am trying to change the value of $rootScope.name that I set in the controller by another function in another controller, but when I access the $rootScope.name in another controller the value remains the same as it was set. For example:
app.controller('homectrl', function($scope, $rootScope){
$rootScope.name = "joshua";
})
app.controller('aboutctrl', function($scope, $rootScope){
$scope.send = function(newname)
{
$rootScope.name = newname;
}
})
app.controller('servicectrl', function($scope, $rootScope){
console.log($rootScope.name); // this outputs joshua instead of new name set in send function in about controller
})

You can not push the button which triggers the send() method fast enough to make the servicectrl output the new name. if you really want to see what is in $rootScope.name after you pushed the button you should observe the value or $watch it, eg. by changing the servicectrl like this:
$rootScope.$watch('name', function(newname) {
console.log($rootScope.name);
});

In a case like that I would avoid using $rootScope, but instead I would use a factory service, shared between the two controllers.
Here is a working example:
var app = angular.module('myApp',[]);
app.controller('homectrl', function($scope, NameService){
$scope.name = NameService.name;
$scope.$watch(function(){return NameService.name}, function(newValue, oldValue){
$scope.name = newValue;
});
});
app.controller('aboutctrl', function($scope, NameService){
$scope.name = NameService.name;
$scope.send = function(newname){
NameService.changeName($scope.name);
console.log('New name!', $scope.name);
}
});
app.factory('NameService', function(){
return {
name : 'joshua',
changeName : function(newName){
this.name = newName;
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="homectrl">
<h3>Home Controller </h3>
<p>{{name}}</p>
</div>
<hr>
<div ng-controller="aboutctrl">
<h3>About Controller </h3>
<input type="text" ng-model="name" />
<button ng-click="send($scope.name)">Change</button>
</div>
</div>

Related

Sharing Data between two controllers

I am using angular 1.x and I am trying to share data from one controller to another
I am using the above model in mainctrl. The radiotmplt.radiohead=='IRU600v3'is from firstctrl. I cannot share data using rootscope. Please advise.
Here is the demo how to share data using RootScope
link Jsfiddle
Js
var app = angular.module('myApp', []);
app.controller('ctrl1', function($scope, $rootScope) {
$scope.data = 'data';
$rootScope.data1 = 'old data';
$scope.setVal = function() {
$rootScope.data1 = 'new data';
}
});
app.controller('ctrl2', function($scope, $rootScope) {
$scope.data = $rootScope.data1;
$scope.$watch('data1', function(o, n) {
$scope.data = $rootScope.data1;
})
});
HTML
<div ng-app='myApp'>
<div ng-controller='ctrl1'>
controller 1
<input type='text' ng-model='data'>
<button ng-click='setVal()'>
Change
</button>
</div>
<hr>
<div ng-controller='ctrl2'>
controller 2
<input type='text' ng-model='data'>
</div>
</div>
Hope this will help you

Unable to update Child controllers scope valriable

Im new to angular js and im not able to figure out how to change the child controller scope variable from parent controller. Here is the code snippet for that:
var mainApp = angular.module("mainApp", []);
var parentCtrl = function($rootScope, $scope, shareService, $log){
shareService.setDetails($scope.pdetails);
}
var mainCtrl1 = function($rootScope, $scope, shareService, $log){
$scope.msg = "Controller 1";
$scope.details = shareService.details;//shareService.details;
}
var mainCtrl2 = function($rootScope, $scope, shareService){
$scope.msg = "Controller 2";
$scope.details = shareService.details;//shareService.details;
}
parentCtrl.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainCtrl1.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainCtrl2.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainApp.controller("parentController", parentCtrl)
.controller("mainController1", mainCtrl1)
.controller("mainController2", mainCtrl2)
.factory("shareService", function(){
var shareData = {
details : "sadfgs detaisdfadsfasdf..",
setDetails: function(value){
this.details = value;
}
};
return shareData;
});
<html>
<head>
<title>Angular JS Views</title>
<script src='lib/angular.js'></script>
<script src='js/mainApp.js'></script>
<script src='js/studentController.js'></script>
</head>
<body ng-app = 'mainApp' ng-controller='parentController' ng-strict-di>
<div ng-controller='mainController1'>
1. Msg : {{msg}}<br/>
Share Details: {{details}}<br/><br/>
</div>
<div ng-controller='mainController2'>
2. Msg : {{msg}}<br/>
Share Details: {{details}}<br/><br/>
</div>
<input type='text' ng-model='pdetails'/>
</body>
</html>
Here is the Plunker link:
https://plnkr.co/edit/hJypukqMmdHSEZMVnkDO?p=preview
In order to change value of child controller from parent controller you can use $broadcast on $scope.
syntax
$scope.$broadcast(event,data);
$broadcast is used to trigger an event(with data) to the child scope from current scope.
In child controller use $on to receive the event(with data).
Here id the code snippet:
app.controller("parentCtrl",function($scope){
$scope.OnClick=function()
{
$scope.$broadcast("senddownward",$scope.messege);
}
});
app.controller("childCtrl",function($scope){
$scope.$on("senddownward",function(event,data)
{
$scope.messege=data;
});
});
In this example I am broadcasting the event on ng-click,you can use some other custom event.like $watch on $scope.
See this example
https://plnkr.co/edit/efZ9wYS2pukE0v4JsNCC?p=preview
P.S. you can change the name of event from senddownward to whatever you want
You can access the parent's scope properties directly due to the scope inheritance:
<div ng-controller='mainController1'>
Share Details: {{pdetails}}
</div>
Your example does not work because the controllers get executed only once before the view is rendered, pdetails is empty at that moment.
To monitor the changes to pdetails, you can use $watch in the child controller:
$scope.$watch('pdetails', function(newVal) {
$scope.details = newVal;
});

Update a service value from a parent controller

I've been searching for hours how to update a service value from a nested controller.
My child controller needs to update a value in a service. And that value needs to be shown in the parent controller.
I've made a jsfiddle to make it more clear and easy to help
http://jsfiddle.net/jtsmduxw/3/
<body ng-app="MyApp">
<div ng-controller="parentCtrl">
<p>{{username}}</p>
<div ng-controller="childCtrl">
<p>{{username}}</p>
</div>
</div>
</body>
-
var app = angular.module("MyApp", []);
app.service('authenticationSrv', function () {
var user = 'anonymous';
return {
getUser: function () {
return user;
},
setUser: function (value) {
user = value;
}
};
});
app.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.username = authenticationSrv.getUser();
});
app.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUser('my name'); // I need this function to also update the scope of the parent
$scope.username = authenticationSrv.getUser();
});
(I've read and tried Update parent scope variable, but I could not make it work with the service.)
Thanks!
Make use of an object literal instead of the variable username.
Parent
app.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.parentObject = {};
$scope.parentObject.username = authenticationSrv.getUser();
});
Child
app.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUser('my name');
$scope.parentObject.username = authenticationSrv.getUser();
});
Working Example
var app = angular.module("MyApp", []);
app.service('authenticationSrv', function () {
var user = 'anonymous';
return {
getUser: function () {
return user;
},
setUser: function (value) {
user = value;
}
};
});
app.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.parentObject = {};
$scope.parentObject.username = authenticationSrv.getUser();
});
app.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUser('my name');
$scope.parentObject.username = authenticationSrv.getUser();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="MyApp">
<div ng-controller="parentCtrl">
<p>{{parentObject.username}}</p>
<div ng-controller="childCtrl">
<p>{{parentObject.username}}</p>
</div>
</div>
</body>
Make user in the Service an object instead of a primitive (string). Then use {{user.name}} in your view.
Notice that I did some minor changes to authenticationSrv.setUser()
and renamed it to authenticationSrv.setUserName().
See my working fiddle: https://jsfiddle.net/rbwk3rqb/
var app = angular.module("MyApp", []);
angular.module("MyApp")
.service('authenticationSrv', function () {
var user = {name: 'anonymous'};
return {
getUser: function () {
return user;
},
setUserName: function (value) {
user.name = value;
}
};
});
angular.module("MyApp")
.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.user = authenticationSrv.getUser();
});
angular.module("MyApp")
.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUserName('my name');
$scope.user = authenticationSrv.getUser();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="MyApp">
<div ng-controller="parentCtrl">
<p>{{user.name}}</p>
<div ng-controller="childCtrl">
<p>{{user.name}}</p>
</div>
</div>
</body>
As user is a primitive value in the service, when you put the value from the service to your controller's scope with this line:
$scope.username = authenticationSrv.getUser();
the value of user is copied into $scope.username. So just because later on you overwrite the value of user in the service, nothing is changing in your "parent" $scope.
There are several ways to get around this, the easiest is probably to create a user object in your service - if you store the reference to this object in your scopes, it will reflect the changes made to it from other controllers. (Objects in javascript are passed by reference value, so all controllers will be affecting the same object, not copies of the values.) For the actual implementation, I'd guide you back to the same link you posted - when you tried implementing that, what was the problem with it? Show us the code you tried.
Alternatively, you can also implement the observer pattern using this service (this is considerably more work), or use events on the scope hierarchy to notify the controllers of the change of user (this is a questionable practice).
The idea is to create and object to update and not just a primitive:
$scope.user = {};
$scope.user.name = authenticateSrv.getUser();
and in the child scope you just set it:
$scope.user.name = authenticateSrv.setUser('my name');
here is a Fiddle

Angularjs - Updating multiple instances of the same controller

My problem: I have multiple instances a controller in my site. When I update 'x', only the current instance/div gets updated.
JSFiddle: http://jsfiddle.net/evgahe2u/ (simplified example, each ng-controller is in its own view.)
HTML
<!-- this is a simplified example -->
<div ng-app="myApp">
<!-- this is in view1.html -->
<div ng-controller="myController">
<input type="text" ng-model="x" /> {{x}}
</div>
<!-- this is in view2.html -->
<div ng-controller="myController">
<input type="text" ng-model="x" /> {{x}}
</div>
</div>
JS
var myApp = angular.module('myApp', []);
myApp.controller('myController', function($scope) {
$scope.x = 'test';
});
My question: How can I have it so when I update View1.html's X value, it will then update view2.html's view?
That's pretty easy.
According to me the best way to do this is to create a factory.
Let's say factory X and let's create two controllers for both views:
myApp.controller('1Ctrl', function($scope, x) {
$scope.x = x.x;
});
myApp.controller('2Ctrl', function($scope, x) {
$scope.x = x.x;
});
myApp.factory('x', function() {
return {
x: 'value'
};
});
Full Example: JSFiddle
Now if X is updated it will update in both controllers, because of the properties of an object. Both x'es on both scopes are the same x.
Broadcast from rootScope
$rootScope.$broadcast("changeXevent", dataToSend);
then handle it with an $on in the controller.
myApp.controller('myController', function($scope, $rootScope) { // inject rootscope
$scope.x = 'test';
// watch for event
$scope.$on('changeXevent', function(event, data){
$scope.x = data;
});
// watch for changes on x
$scope.$watch('x', function(newValue, oldValue){
if(newVal !== oldVal)
$rootScope.$broadcast('changeXevent', $scope.x);
});
});

Angularjs call function when the controller is load

I have a little problem with controllers in AngularJs.
I have one controllers and some other controllers into the first controller. Basically i have this :
<body ng-app="scopeInheritance">
<div class="spicy">
<div ng-controller="MainController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<div ng-controller="ChildController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<p ng-if="valide()">Heelo i'm the if</p>
</div>
</div>
</div>
</body>
And my .js
var myApp = angular.module('scopeInheritance', []);
myApp.controller('MainController', ['$scope', function($scope) {
$scope.timeOfDay = 'morning';
$scope.name = 'Nikki';
$scope.testCtrl1 = true;
}]);
myApp.controller('ChildController', ['$scope', function($scope) {
$scope.name = 'Mattie';
$scope.timeOfDay = 'aternoon';
$scope.test = true;
$scope.valide = function () {
alert("i'm the function validate");
if($scope.testCtrl1 && $scope.test)
return true;
};
}]);
I want to call the function valide() to show some text. The function can return true or false depending of the value one the controller ChildController
The problem is : the function valide() is calling at every controllers.
This is normal, but how can i limite that ? The function valide() need to be call when the controller ChildController is load.
Maybe it was unclear, i made a live exemple : http://plnkr.co/edit/AM9loq4VRkL16mX8LR1v?p=preview
You can see two alert.
EDIT = valide() return true or false, depending on the value of the controllers ChildController and MainController

Categories

Resources