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);
});
});
Related
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
I am wondering at the dual behaviour of $scope. In the below script I am getting value of name as alert. But in my ionic app the same code alerts undefined.
I googled the problem and found this link as a solution where it states that we need to use dot(.) in order to get the value in ng-model. What is the difference between two.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a =function a(){alert($scope.name);}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="name" ng-blur="a()">
</div>
Try changing your controller function as below:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a =function(){
alert($scope.name);
}
});
Actually it does work with Ionic,
angular.module('starter.controllers', [])
.controller('myCtrl', function($scope) {
$scope.a = function a() {
alert($scope.name);
}
})
DEMO
Solution :
"If you use ng-model, you have to have a dot in there."
Make your model point to an object.property and you'll be good to go.
Controller
$scope.formData = {};
$scope.check = function () {
console.log($scope.formData.searchText.$modelValue); //works
}
Template
<input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>
This happens when child scopes are in play - like child routes or ng-repeats.
The child-scope creates it's own value and a name conflict is born as illustrated here:
See this video clip for more: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s
.
And that is referred from below links :
Other Solutions
Use this keyword instead of $scope, More details
And also you can get more details from this below two discussions
Ng-model does not update controller value
Why is my ng-model variable undefined in controller?
Update Solution 1 :
Please declaring the blank object first at the top of your controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "";
$scope.a = function(){alert($scope.name);}
});
I hope these will be helps to you.
Try to use json object.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.user = {'name':''};
$scope.a =function a(){alert($scope.user.name);}
});
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="user.name" ng-blur="a()">
</div>
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;
});
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>
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