I have two controllers:
<div ng-controller="Main">
<div ng-controller="Map"></div>
</div>
In controller Main I have variable $scope.mapCoord;
How I can to pass this variable in controller Map?
Use a service. For example:
var app = angular.module('myApp', [])
app.service('sharedProperties', function () {
var mapCoord= 'Test';
return {
getProperty: function () {
return mapCoord;
},
setProperty: function(value) {
mapCoord= value;
}
};
});
Inside your Main controller
app.controller('Main', function($scope, sharedProperties) {
$scope.mapCoord= sharedProperties.setProperty("Main");
});
Inside your Map controller
app.controller('Map', function($scope, sharedProperties) {
$scope.mapCoord= sharedProperties.getProperty();
});
Here's a fiddle for you. JSFiddle
You use events to pass it between controllers using by $broadcast, $emit and $on
Working with $scope.$emit and $scope.$on
http://mariuszprzydatek.com/2013/12/28/sharing-data-between-controllers-in-angularjs-pubsub-event-bus-example/
In your "Map" controller, set "Main" scope to current scope such as below :
app.controller('Map', ['$scope','$controller',function($scope, $controller) {
$controller('Main', {
$scope : $scope
});
}]);
After that you can access all the scope of Main controller from his son controller :
app.controller('Map', ['$scope','$controller',function($scope, $controller) {
$controller('Main', {
$scope : $scope
});
var coord = $scope.mapCoord;
}]);
Related
I have two controllers ParentController and ChildController I have a variable in ParentController and i need to get that variable to ChildController and then i need to pass it to the view and one more thing is i should not use the $scope in child controller and parentController. Is it possible ?if not is there any way to use it with out $scope.
app.controller('ParentController', function($scope) {
$scope.exampleVariable = "test";
});
app.controller('ChildController', function($scope, $controller) {
var someScopeVariable = this;
$controller('ParentController', {$scope: someScopeVariable });
console.log(someScopeVariable.exampleVariable)
someScopeVariable.exampleVariable = "Updatetest";
});
Now in my html view i need to use exampleVariable
like this
<div ng-controller="ChildController as child">
<h1>{{child.exampleVariable}}</h1>
</div>
How can i get the value from parentcontroller to html view.
You can always use a service to share data between controllers.
create a service
app.service('myservice', function() {
var myVar;
this.setMyVar = function(value){
this.myVar = value
}
this.getMyVar = function(){
return this.myVar;
}
});
pass it as a dependency and you can have the value shared.
app.controller('ParentController',['$scope', 'myservice', function($scope, myservice) {
$scope.exampleVariable = "test";
myservice.setMyVar("test");
}]);
you can pass it to other controller as a dependency too and you can do a getMyVar there!!
You can use Broadcast and On in the Controller-
app.controller('ParentController', function($scope) {
var self = this;
$scope.$broadcast('exampleVariable', 'test');
});
and in child controller -
app.controller('ChildController', function($scope, $controller) {
var someScopeVariable = this;
$controller('ParentController', {$scope: someScopeVariable });
console.log(someScopeVariable.exampleVariable)
$scope.$on('exampleVariable', function(event, data) {
someScopeVariable.exampleVariable = data;
});
});
There are some ways you can achieve this.
1. Through $rootScope.
2. By Creating Service.
3. Inheriting parent controller to children controller.
2 & 3 are already provided in other answers. Follow this if you want to achieve it using $rootScope.
JS :
var app = angular.module('myApp', []);
app.controller('ParentController', function($scope, $rootScope) {
$rootScope.exampleVariable = "test";
});
app.controller('ChildController', function($scope) {
});
HTML :
<div ng-controller="ParentController">
Parent Controller : {{exampleVariable}}
<hr/>
</div>
<div ng-controller="ChildController">
Children Controller : {{exampleVariable}}
</div>
DEMO LINK.
Note : You can also override the scope variable in children controller by adding the below code in ChildController :
$scope.exampleVariable = "overriding...";
I have this controller A which I'm trying to inject in every other controller.
What controller A does is, it communicates with a factory (which does some authentication services, communicates with database)
My factory looks like this and I named it myFactoryServices.js and included the link to it in my index page.
(function() {
angular
.module('myApp.myFactoryServices', [])
.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
})();
and my Controller A looks like this:
(function() {
angular
.module('myApp.ControlA', [])
.controller('ControllerA', function($scope,$routeParams, FactoryService) {
var my = this;
FactoryService.someFunction();
});
})();
And I am trying to inject this controller in every other controller, but it does not work. I am pretty new to this kind of programming, can anyone tell me where I made mistake?
This is how I tried injecting a controller into another.
(function() {
angular
.module('myApp.ControlB', [])
.factory('ControllerBService', function($http) {
var baseUrl = 'backendurl/';
return {
getInfo: function() {
return $http.get(baseUrl+ 'getInfo');
}
};
})
.controller('ControllerB', function($scope,$routeParams, ControllerBService,ControllerA) {
var my = this;
});
})();
No error is coming, and the controller is not getting injected as I am not able to use those factory services. is this the correct method?
First of all you cannot inject controller to another controller, and One simple solution would be, instead of having each angular modules for each components, declare a module and add the factory service to controllers as dependency.
Code:
var app = angular.module('myApp', []);
app.factory('FactoryService', ["$http", "$location", function($http, $location){
var my = this;
my.someFunction = function()
{
//communiate with backend and return data
}
return my;
}]);
app.controller('ControllerA', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});
app.controller('ControllerB', function($scope,$routeParams, FactoryService)
{
var my = this;
FactoryService.someFunction();
});
Controllers are not injectable, because controller is not singleton. Controllers are constructor functions used to create instances of controllers. For example you can have multiple instances of one controller in your app:
angular.module('app', []);
angular
.module('app')
.controller('Example', function () {
this.x = Math.random();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app="app">
First instance: <br>
<div ng-controller="Example as Ex1">
{{Ex1.x}}
</div>
Second instance: <br>
<div ng-controller="Example as Ex2">
{{Ex2.x}}
</div>
</div>
So if you want to share some behavior between controller you should use factory instead.
To inject a controller into another controller, use the $controller service.
app.controller('ControllerB', function($scope,$routeParams, $controller) {
var my = this;
$scope.ctrlA = $controller("ControllerA", {$scope: $scope});
});
The above example creates an instance of ControllerA as ctrlA with its $scope injected with the scope of the parent controller.
For more information, see AngularJS $controller Service API Reference.
I have HTML code:
<div ng-controller="ProfileLeftMenu">
<li ng-class="{'active':selectedTab == 'personal'}" ng-click="selectedTab = 'personal'" class="">Personal
</li>
</div>
And controller:
$scope.selectedTab = 'first';
if ($routeParams.page) {
ajax.get(page, function (CbData) {
$scope.selectedTab = page;
});
}
So, if do:
{{selectedTab}}
in template HTML get always: first
You need to update your $scope variable with the new $routeParams just after the change in route. For that you can listen for the$routeChangeSuccess event. Try this:
DEMO
app.js
var app = angular.module('plunker', ['ngRoute']);
app.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/test/:page', {
templateUrl: function(params) {
return 'pidat.html';
},
controller: 'MainCtrl'
});
}
]);
app.controller('MainCtrl', ['$scope', '$http', '$routeParams', function($scope, $http, $routeParams) {
// when controller is loaded params are empty
console.log('on controller load $routeParams', $routeParams);
$scope.name = 'World';
// only after you have transitioned to the new
// route will your $routeParams change so we
// need to listen for $routeChangeSuccess
$scope.$on('$routeChangeSuccess', function(){
console.log('on $routeChangeSuccess load $routeParams', $routeParams);
if ($routeParams.page) {
$scope.name = $routeParams.page;
}
});
}]);
So for your original example you would probably have to do something like this:
$scope.selectedTab = 'first';
$scope.$on('$routeChangeSuccess', function(){
if ($routeParams.page) {
ajax.get(page, function (CbData) {
$scope.selectedTab = page;
});
}
});
Use the angular $http service ($http.get()), not ajax.get(). Otherwise, Angular isn't aware of the change you make to the scope once the HTTP response comes and the callback is executed, unless you call $scope.$apply().
Consider we have some directive with templateUrl and controller.
angular.module('someApp').directive('myDirective', [function() {
return {
templateUrl:'someTemplate.html',
controller: ['$scope', function($scope) {
this.someFunction = function() {}
}]
}
}])
If we try to get controller now
var directive = angular.element('<my-directive />');
$compile(directive)( scope );
var controller = directive.controller('myDirective');
the controller is undefined.
The answer is to set a template instead of templateUrl in the directive.
angular.module('someApp').directive('myDirective', [function() {
return {
template:'<span>Solution!</span>',
controller: ['$scope', function($scope) {
this.someFunction = function() {}
}]
}
}])
I can't find anything about it in documentation. I think it's a bug.
Say I have a factory named MyFactory and I inject it into several controllers. How can I access the controllers scope inside the factory?
The only way I currently think of on how to do this is as follows:
app.factory('MyFactory', function() {
return function($scope) {
myPublicFunc: function() {
$scope.$on('$destroy', function() { ... });
}
}
});
app.controller('MyController1', ['$scope', MyFactory', function($scope, Myfactory) {
var factory = new MyFactory($scope);
factory.myPublicFunc();
});
But is there any other way where I can just return { } instead of function($scope) { } in MyFactory and use the factory directly (MyFactory.myPublicFunc) instead of having to create a new instance with the new keyword and still access each controller's $scope?
if you use a .service instead of .factory you will already have a singleton instance in a controller once you inject it via DI
and then you can do for example
module.service('myService', function() {
return {
myPublicFn: function() {}
}
});
and
module.controller('myCtrl', function(myService, $scope) {
$scope.publicFn = myService.myPublicFn;
});