AngularJS - Sharing variables between controllers
Use Angular JS Services/ Factories
A sample example is shown below
Working Demo
HTML
<div ng-app='myApp'>
<div ng-controller="ControllerOne">
<button ng-click="getUserOne()">User One</button>
</div>
<div ng-controller="ControllerTwo">
<button ng-click="getUserTwo()">User Two</button>
</div>
</div>
SCRIPT
var app = angular.module('myApp', []);
app.factory('userFactory', function () {
return {
users: [{
userId: 1,
userName: "Jhonny"
}, {
userId: 2,
userName: "Sunny"
}]
}
});
app.controller('ControllerOne', function ($scope, userFactory) {
$scope.getUserOne = function () {
alert(JSON.stringify(userFactory.users[0]));
}
});
app.controller('ControllerTwo', function ($scope, userFactory) {
$scope.getUserTwo = function () {
alert(JSON.stringify(userFactory.users[1]));
}
});
Also take a look at this stuff
How can I pass variables between controllers in AngularJS?
AngularJS: How can I pass variables between controllers?
One way to share variables across multiple controllers is to create a service and inject it in any controller where you want to use it.
Simple service example:
angular.module('myApp', [])
.service('sharedProperties', function () {
var property = 'First';
return {
getProperty: function () {
return property;
},
setProperty: function(value) {
property = value;
}
};
});
Using the service in a controller:
function Ctrl2($scope, sharedProperties) {
$scope.prop2 = "Second";
$scope.both = sharedProperties.getProperty() + $scope.prop2;
}
This is described very nicely in this blog (Lesson 2 and on in particular).
I've found that if you want to bind to these properties across multiple controllers it works better if you bind to an object's property instead of a primitive type (boolean, string, number) to retain the bound reference.
Example: var property = { Property1: 'First' };
instead of var property = 'First';
.
UPDATE: To (hopefully) make things more clear here is a fiddle that shows an example of:
- Binding to static copies of the shared value (in myController1)
- Binding to a primitive (string)
- Binding to an object's property (saved to a scope variable)
- Binding to shared values that update the UI as the values are updated (in myController2)
- Binding to a function that returns a primitive (string)
- Binding to the object's property
- Two way binding to an object's property
Passing data between controllers in Angular JS?
From the description, seems as though you should be using a service. Check out http://egghead.io/lessons/angularjs-sharing-data-between-controllers and AngularJS Service Passing Data Between Controllers to see some examples.
You could define your product service (as a factory) as such:
app.factory('productService', function() {
var productList = [];
var addProduct = function(newObj) {
productList.push(newObj);
};
var getProducts = function(){
return productList;
};
return {
addProduct: addProduct,
getProducts: getProducts
};
});
Dependency inject the service into both controllers.
In your ProductController
, define some action that adds the selected object to the array:
app.controller('ProductController', function($scope, productService) {
$scope.callToAddToProductList = function(currObj){
productService.addProduct(currObj);
};
});
In your CartController
, get the products from the service:
app.controller('CartController', function($scope, productService) {
$scope.products = productService.getProducts();
});
Passing variables between controllers using AngularJS
Factory is a singleton so it can be used to share data among different controllers or directives. Take a look at the fiddler here. I have created a factory 'sharedContext' which can be used to share any key-value pair across controllers using different $scope.
Factory
myApp.factory("sharedContext", function() {
var context = [];
var addData = function(key, value) {
var data = {
key: key,
value: value
};
context.push(data);
}
var getData = function(key) {
var data = _.find(context, {
key: key
});
return data;
}
return {
addData: addData,
getData: getData
}
});
From the controller that needs to share the object can call the 'addData' method of the factory to store the data under a key. The other controllers/directives which are interested in accessing the shared data can do so by calling the 'getData' method and passing the correct key.
Controller (Sharing Data)
function MyCtrl_1($scope, sharedContext) {
$scope.input_1 = 5;
$scope.input_2 = 15;
$scope.add = function() {
$scope.result = $scope.input_1 + $scope.input_2;
sharedContext.addData("Result", $scope.result)
}
}
Controller (accessing shared data)
function MyCtrl_2($scope, sharedContext) {
$scope.getData = function() {
$scope.result = sharedContext.getData("Result").value;
}
}
The only assumption here is that both the controllers need to use the exact key to share the data. To streamline the process you can use a constant provider to share the keys. Also note that I have used underscore.js to look for the key in the shared context dictionary.
AngularJS - share variable between two controllers
time
appears to be a primitive, which means it is returned byVal rather than byRef. In other words, each call to getTime
will return the value that time
is currently set to, and calls to setTime
will change the value for future calls, but not for anything that already called it. This is a classic case of the angular rule, Always use a dot.
Try changing time
to an object instead:
.factory('Timeline', function() {
var timelines = [];
var time = {
value: null
};
return {
getTime: function() {
return time;
},
setTime: function(_time) {
time.value = _time;
}
}
});
In your HTML, use {{time.value}}
.
How do I pass variables to a sibling controller
Inject into the dialog box controller using the resolve property of ngDialog.open(), like this:
ngDialog.open({
template: 'POLine.html',
className: 'ngdialog-theme-default',
controller: 'POLineController',
controllerAs: 'poline',
resolve: {
poNumber: function () {
return po.purchaseOrderNumber;
}
}
})
Then in POLineController:
function POLineController(poNumber) {
poline = this;
poline.lineNumber = poNumber;
poline.desc = "THIS IS A DESCRIPTION";
}
UPDATE
Here's a working plunk
Pass variables to AngularJS controller, best practice?
You could create a basket service. And generally in JS you use objects instead of lots of parameters.
Here's an example: http://jsfiddle.net/2MbZY/
var app = angular.module('myApp', []);
app.factory('basket', function() {
var items = [];
var myBasketService = {};
myBasketService.addItem = function(item) {
items.push(item);
};
myBasketService.removeItem = function(item) {
var index = items.indexOf(item);
items.splice(index, 1);
};
myBasketService.items = function() {
return items;
};
return myBasketService;
});
function MyCtrl($scope, basket) {
$scope.newItem = {};
$scope.basket = basket;
}
Related Topics
Is the JavaScript Date Object Always One Day Off
Why Does String to Number Comparison Work in JavaScript
How to Get the Youtube Video Id from a Url
JavaScript - Generating Combinations from N Arrays With M Elements
Get the Scale Value of an Element
How to Inject CSS into Webpage Through Chrome Extension
Dynamically Expand Height of Input Type "Text" Based on Number of Characters Typed into Field
Shell Tool Which Renders Web Site Including JavaScript
How to Group Data with an Angular Filter
Es6 Class Variable Alternatives
Get the Real Width and Height of an Image With JavaScript? (In Safari/Chrome)
How to Pass Command Line Arguments to a Node.Js Program
Fastest Method to Replace All Instances of a Character in a String
Change CSS Properties on Click
Event Listener on a CSS Pseudo-Element, Such as ::After and ::Before