I have 2 controller say cont_a and cont_b which has function fun_a() and fun_b() respectively.
I have a button inside cont_a and if I click on it it should call both function, and I have no idea from where to begin with.
Thank you.
Two options, use a service or use an angular event
Service approach
app.service('funcService', function(){
this.fun_a = function (){
alert('fun_a')
}
this.fun_b = function (){
alert('fun_b')
}
}
app.controller('Ctrl_1' , function($scope,funcService){
$scope.callBothFunctions = function(){
funcService.fun_a();
funcService.fun_b()
}
});
app.controller('Ctrl_2' , function($scope,funcService){
$scope.func_b = funcService.func_b;
});
Event approach
app.controller('Ctrl_1' , function($scope,$rootScope){
$scope.fun_a = function (){
alert('fun_a');
$rootScope.$broadcast('call-fun_b');
}
});
app.controller('Ctrl_2' , function($scope){
$scope.fun_b = function (){
alert('fun_b')
}
$scope.$on('call-fun_b', function(){
$scope.fun_b();
})
});
Beyond this, question is too vague to know what best approach is. Generally using services is best way to keep controller code lean
Related
hi all i am using angulrajs passing one value from one controller to another controller using service it's work fine but my need is when service value change in controller 2 i get the service value in one scope when scope value change i need trigger the function it's called refresh function when service value change and that i need to call the refresh function here my fiddle
https://jsfiddle.net/ctawL4t3/10/
You can just $watch your value.storeObject. Though it's not best of the practices, but it suits this kind of feature.
$scope.$watch('value.storedObject', function(newVal) {
if(newVal !== '') {
refresh()
}
})
working fiddle (open console to see refresh function logging)
You can try to use angular default $emit, $broadcast, or try to do 2 simple functions in own service
angular.module('app').factory('StoreService', function() {
var listeners = {};
var emit = function(name, val) {
if(listeners[name]) {
listeners[name](val)
}
}
var on = function(name, callback) {
listeners[name] = callback;
}
return {
emit: emit,
on: on,
storedObject: ''
};
});
JSFiddle example
JSFiddle example $watch
JSFiddle example ng-change is better because, you can use easily debounce
you can use broadcast function for that
Please check this SO link to find the related answer
How to call a function from another controller in angularjs?
app.controller('One', ['$scope', '$rootScope'
function($scope) {
$rootScope.$on("CallParentMethod", function(){
$scope.parentmethod();
});
$scope.parentmethod = function() {
// task
}
}
]);
app.controller('two', ['$scope', '$rootScope'
function($scope) {
$scope.childmethod = function() {
$rootScope.$emit("CallParentMethod", {});
}
}
]);
I have a function that I'm now needing to use in multiple page so decided to move into a service - however its not going as I'm expecting.
So in my HTML i have:
<li ng-init="bg = underQBar(work.options)">
Then in the controller (before I moved the common function) it looked like:
$scope.underQBar = function(toWorkArray) {
//some implementation, with a return at the end
}
Now I've made my service:
function barService($window){
var self = this;
self.getBarColours = function(toWorkArray) {
//copied the implementation with the return here
}
}
And therefore trying this in my controller:
$scope.underQBar = barService.getBarColours(toWorkArray);
However this doesnt work, its not getting the parameter I'm sending from the HTML - is this a trivial fix or something wrong with the implementation?
This is the problem:
$scope.underQBar = barService.getBarColours(toWorkArray);
Here, you're assigning the result of the service function call to $scope.underQBar, when you meant to assign it the function itself.
This should work:
$scope.underQBar = barService.getBarColours;
If you want to make it more clear to the reader that it's a function, just do:
$scope.underQBar = function (toWorkArray) {
return barService.getBarColours(toWorkArray);
}
Here is a correct definition for your service :
angular.module("myModule").factory("BarService", ["$window", function($window){
var service = {};
service.getBarColours = function(toWorkArray){
//copied the implementation with the return here
};
return service;
}]);
And here is a correct way to inject the service in your controller :
angular.module("myModule").controller("controllerName", ["BarService", function(BarService){
var self = this;
self.getBarColours = BarService.getBarColours;
}]);
and here is the way to use it:
<li ng-init="bg = controllerName.underQBar(work.options)">
Explanation :
A service or a factory in angular cannot be accessed by your view. Your view can only make a call to your controllers.
If your function should have been called by many controllers, you can put this function in a global controller that will be responsible for controlling your whole view.
Hello I'm new in angularJS. Suitable or not to implement function inside function?
For example like this:-
$scope.loadDistrict = function(id) {
// statement
$scope.loadBasedOnYear = function(y_id) {
console.log(y_id);
// statement
};
};
If you bind method on scope, it's available from view.
From your code
$scope.loadDistrict = function(id) {
// statement
$scope.loadBasedOnYear = function(y_id) {
console.log(y_id);
// statement
};
};
loadBasedOnYear won't available until loadDistrict is called.
It's very bad pattern to follow.
It is possible but without context I don't really know why you would do this, calling $scope.loadBasedOnYear before calling $scope.loadDistrict will result in an error so be careful with such a design pattern.
Yes this is fine.
You should watch out for when the function will be executed outside of angular's cycle. E.g. if you do:
setTimeout(function() { $scope.test = 5; }, 1000);
If you need to do this then you need to wrap the function in $scope.$apply(), or use $timeout.
I have controller (say BaseCtrl) that has a number of functions attached to it. I want to extend BaseCtrl to other controllers that shares some of its functions, however, I only need a function or two (and not all of BaseCtrl's functions). I already saw some posts that demonstrates how to extend a controller, but I wonder if it's possible to extend specific functions only and how to do it?
Extending my comment:
app.controller('parentCtrl', function($scope,$rootscope) {
$rootscope.myPerent = function () {
//your code
}
});
app.controller('childCtrl', function($scope,$rootscope) {
$scope.ourPerent = function () {
$rootscope.myPerent();
}
});
I have two factories as follows:
angular.module('categoryResource', ['ngResource', 'userResource'])
.factory('categories', function ($http, users){
var factory = {};
factory.getCategories = function () {
return $http.get('/api/userCategories');
};
factory.getCategoriesUsers = function () {
//call factory.getCategories(), parse the request to make it nice and tidy
//then call users.getUsers(), tidy them up in the same way as categories, join them together and return them all in a nice package.
};
var handleCategoriesUsers = function (data, status) {
}
return factory;
});
angular.module('userResource', ['ngResource'])
.factory('users', function ($http) {
var factory = {};
factory.getUsers = function () {
return $http.get('/api/users');
};
return factory;
});
I've already made a nice treeView with the Categories but I want to also add Users to those categories; so to this end I thought I'd just format the users into something my treeView algorithm can already work with.
My question is, Can I somehow do It within the categories factory (or even a different module/factory altogether) and just return the joined results at the same time? If yes, how? Do I need to define a handler for $http.get like I usual? then in that handler, call the other get then define a handler for that and then return the result?
I'm not 100% sure I understand the question, but have you looked at $q.all? It seems like you want to compose/combine multiple promises into a single, easy to handle package. I'd give you a description and some code samples, but egghead did it better: https://egghead.io/lessons/angularjs-q-all
Is this what you're looking for?
EDIT: In case just dumping a link is frowned upon:
var all = $q.all([one.promise, two.promise, three.promise]);
all.then(success)
function success(data) {
console.log(data);
}