'use strict';
angular.module('sampleApplicationApp').config(function($stateProvider)
{
$stateProvider.state('abcmanagement', {
parent : 'parentmanagement',
url : '/em',
views : {
'content#' : {
templateUrl : 'scripts/app/abc.html',
controller : 'abcController'
}
}
}).state('newmodel', {
parent : 'abcmanagement',
url : '/new',
views : {
'content#' : {
templateUrl : 'scripts/app/xyz.html',
controller : 'xyzController'
}
}
})
});
angular.module('sampleApplicationApp')
.controller('abcController', function ($scope, $state, $modal) {
$scope.models = {};
// logic to load models
});
angular.module('sampleApplicationApp')
.controller('xyzController', function ($scope, $state, $modal) {
// I want to access models from above controller
});
Is there a possibility i can have access to models defined in abcController from xyzController ?
two options:
if the controllers inherit from the same parent controller, you can store the data in the parent $scope (or $rootScope, but that's bad practice);
if the controllers do not inherit from the same parent controller, use a factory to share data between controllers:
`
angular.module('sampleApplicationApp')
.factory('abcModel', function () {
var factory = {};
var model = {};
factory.setModel = function(key, value) {
model[key] = value;
}
factory.getModel = function(key) {
return model[key];
};
return factory;
});
angular.module('sampleApplicationApp')
.controller('abcController', function ($scope, $state, $modal, abcModel) {
abcModel.setModel('abc', "hello world");
});
angular.module('sampleApplicationApp')
.controller('xyzController', function ($scope, $state, $modal, abcModel) {
$scope.value = abcModel.getModel('abc');
});
You have, potentially, as many as three options:
1) If xyzController resides within abcController within your HTML then you can reference $parent.property ('property' being the name of the $scope property in the parent controller you want access to).
2) You could use $rootScope by setting any properties you want to access in multiple controllers like so, $rootScope.property. I would recommend avoiding this as it could pollute the global scope.
3) You could use an Angular service with methods for getting and setting the variables in question. Then you could simply inject this service as a dependency in each controller where you need access to these variables. Recommended approach
The best practice is that you should create an Angular service which holds the variable.
You can work around it by using the $rootScope. Don't forget to inject it in both controllers ;)
There are many ways to achieve what you are trying to do.You can create a factory or a service,you can use $rootScope(not recommended),you can use angular's broadcast, emit method to achieve this.Refer to this example http://stackoverflow.com/questions/21919962/share-data-between-angularjs-controllers
Related
UPDATE PLEASE HELP:
Tried what you suggested, the problem is when i try to pass the value to another "Module". Tried creating a service but the function didn't work, maybe i missed something.
Made Example Using rootScope:
var informes = angular.module('informes', ['angular-drupal', 'ui.bootstrap']);
informes.controller('InformesCtrl', ['drupal', '$rootScope', '$scope', '$http', 'InformesFtry', function(drupal, $rootScope, $scope, $http, InformesFtry) {
$rootScope.nodeID = function(item){
var item = "hi";
console.log(item);
}
}]);
Console hi
It works in first module, but...
In my other Module with different Page...
var nodeInformes = angular.module('node-informes', ['informes']);
nodeInformes.controller('NodeInformesCtrl', ['drupal', '$rootScope', '$scope', '$http', 'InformesFtry', function(drupal, $rootScope, $scope, $http, InformesFtry) {
$scope.nodeID2 = $rootScope.nodeID(item);
console.log($scope.nodeID2);
}]);
Console: item is Undefined
I'm trying to figure out of how can i pass a function to another module, but it seems that it is impossible. I didn't try to use same module, but it works if the controller is child from the first controller.
I really apprecaite any help you can provide me to pass a function with parameter to another module with another controller. I'm trying to learn with this. Thanks!!!
EDIT: If i add the firstcontroller as a dependency it gives me Unknown Provider... Sorry for my mistake.
In Angular JS there are three ways for controllers to communicate with other controllers, and any other method is asking for trouble:
Use a service:
Use a service as an intermediary between controllers:
function MyService() {
this.MyObject = {};
}
function ctrl1(MyService) {
Myservice.MyObject = {
someData: "someValue"
};
}
function ctrl2(MyService) {
$scope.someValue = MyService.MyObject.someData;
}
Use the event system
function ctrl1($rootScope) {
$rootScope.$broadcast("my-event", {someData: "someValue"});
}
function ctrl2($scope) {
$scope.$on("my-event", function(event, params) {
$scope.someData = params.someData;
});
}
Scope inheritence
<div ng-controller="ctrl1">
<div ng-controller="ctrl2">
</div>
</div>
function ctrl1($scope) {
$scope.someData = "someValue";
}
function ctrl2($scope) {
console.log($scope.$parent.someData); //"someValue"
}
I have a google material dialog box where I interact with the user. I want to inject a factory into the dialog and use it there. Is there a way to do this?
I tried passing the factory as a local variable.
Any suggestions?
Edit ---------
Here is my controller that I am using to handle the dialogs. I output the factory to the console and the functions are all there. Not sure why calling them does nothing.
function DocumentDialogController($mdDialog, locals, chartFactory)
{
var vm = vm || this;
vm.thisItem = locals.thisItem;
vm.cancel = cancel;
vm.acceptChanges = acceptChanges;
vm.selectImage = selectImage;
function cancel(){
$mdDialog.cancel();
};
function acceptChanges(desc) {
$mdDialog.hide(desc);
};
function selectImage(imageName) {
vm.thisItem.imageObj.data.src=imageName;
};
}
Assign a controller to the dialog and inject the factory into the controller.
Do something like the below to create the dialog. Note that the string in the controller property is the name of the controller you want to use.
$mdDialog.show({
templateUrl: 'partials/example.template.html',
targetEvent: event,
controller: 'ExampleCtrl',
controllerAs: 'vm'
});
Create and inject the factory into the controller like you would with any other controller.
(function() {
'use strict';
angular
.module('example')
.controller('ExampleCtrl', ExampleCtrl);
function ExampleCtrl(ExampleFactory) {
var vm = this;
// you can now use the injected ExampleFactory
}
ExampleCtrl.$inject = ['ExampleFactory'];
})();
Context:
I'm using Angular and ui-router...
I have a parent controller "ParentCtrl" with a template "ParentTempl".
Within the ParentTempl there is a view for 2 states: add and edit.
I want call a function from the ParentCtrl "abstractUpdate" that changes its behavior based on which state is active.
Current Code:
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('add', {
template: "...",
abstractUpdate = function(object){
// do add things
}
})
.state('edit', {
template: "...",
abstractUpdate = function(object){
// do edit things
}
});
}
app.controller('ParentCtrl', function ($scope, $state) {
$scope.click = function(obj){
$state.current.abstractUpdate(obj);
}
}
Question:
The current version is working, but you think it is the best solution? Any suggestions?
Usually you would use a factory or service for something like this. That way you don't clog up your routing with application logic. You could just inject $state into your factory/service so you can handle things based on the state you're in:
angular.module('myApp').factory('MyService', [
'$state',
function ($state) {
return {
myMethod: function (obj) {
if (this.hasOwnProperty($state.current.name)) {
this[$state.current.name](obj);
}
},
add: function (obj) {
// do stuff
return obj;
},
edit: function (obj) {
// do stuff
return obj;
}
}
}
]);
Now you can use your service from any controller you want, just inject it:
angular.module('myApp').controller('myController', [
'$scope',
'MyService',
function ($scope, MyService) {
$scope.obj = {};
$scope.obj = MyService.myMethod(obj);
}
]);
It would be more clear to have two separate functions that each perform their separate tasks. It's a better programming habit, imo.
You can create a controller for each of your child views and still have ParentCtrl as a parent for each. Each child controller can have its own click handler which calls either the 'edit' or 'new' method on the parent (unless it makes more sense to put that code entirely or partially on each child controller).
I have some issue with AngularJS scope and location. Here is an example :
function CreateAccountCtrl($scope, $http, $location) {
...
$http.post(url,$scope.form).
success(function(data){
$location.path('/'); // I need to transfert data to the location
}
}
My problem is : I want to transfer the data to the / controller, I thought to use the rootScope but I don't think it is the best way to do this.
Any idea ?
You can use $rootScope to send data between controllers. $routeParams doesn't allow send complex data structures.
Let's see it.
Assign returned data of success callback to variable in $rootScope.
Navigate to the AccountController.
function CreateAccountCtrl($scope, $http, $location,$rootScope ) {
...
$http.post(url,$scope.form).
success(function(data){
$rootScope.accountInfo = data;
$location.path('/account');
}
}
Configure the route in the $routeProvider:
$routeProvider.when('/account', {
template: 'account.html',
controller: AccountCntl
});
In the AccountController can access the data on $rootScope.
function AccountCtrl($scope, $rootScope) {
$scope.accountInfo = $rootScope.accountInfo;
}
Use the $routeParams service.
function CreateAccountCtrl($scope, $http, $location) {
...
$http.post(url,$scope.form).
success(function(data){
$location.path('/account/' + data.accountId);
}
}
Configure the route in the $routeProvider:
$routeProvider.when('/account/:accountId', {
template: 'account.html',
controller: AccountCntl
});
Your AccountController can now access the data:
function AccountCtrl($scope, $routeParams) {
$scope.accountId = $routeParams.accountId;
}
There is a lot of reusable functionality that I have defined in my application that EVERY controller uses with the $scope variable. Instead of me having to create a shared service each time, is there a way to extend the $scope variable so that I can have my extended code available everywhere?
Something like:
//I've tested this out and it doesn't work, but this is what I want to do.
angular.module('App',[]).config(['$scopeProvider',function($scope) {
$scope.method1 = function() { ... };
$scope.method2 = function() { ... };
}]);
Then later on:
var HomeCtrl = function($scope) {
$scope.method1();
};
Is this possible? Or do I need to create a shared service and then have the $scope extend from that for the first line of each controller?
Instead of .config try .run, this will do exactly what you want.
angular.module('App', []).run(['$rootScope', function($rootScope) {
$rootScope.foo = function() {
alert("WIN!");
};
}]);
angular.module('App').controller('HomeCtr', ['$scope', function($scope) {
$scope.foo(); #will call the alert
}]);
NOTE I have only used module.controller because I like it, var HomeCtrl = function($scope) { will have the same effect.