How can I call function loadTable from another controller?
app.controller('tableCtrl', ['$scope', function (scope) {
scope.loadTable = function() {
//some code
};
});
app.controller('secondCtrl', ['$scope', function (scope) {
scope.buttonClick = function() {
//call loadTable from tableCtrl
};
});
Try $emit-$on(publish-subscribe) mechanism.
app.controller('tableCtrl', ['$scope', function (scope) {
scope.loadTable = function() {
//some code
};
$rootScope.$on('load-table', function (event, arg1, arg2) {
// now trigger the method.
scope.loadTable();
});
});
app.controller('secondCtrl', ['$scope', function (scope) {
scope.buttonClick = function() {
//call loadTable from tableCtrl
//emit the event
$rootScope.$emit('load-table', 'arg1', 'arg2');
};
});
You should perhaps use a service such as
app.factory('tableService', [function () {
return {
loadTable : function() {
//some code
}
};
});
app.controller('tableCtrl', ['$scope', 'tableService', function (scope, tableService) {
});
app.controller('secondCtrl', ['$scope', 'tableService', function (scope, tableService) {
scope.buttonClick = function() {
tableService.loadTable();
};
});
Your tableCtrl would then need to save any data using another function on the service.
Related
I'm using the ui-bootstrap modal window and I'm trying to test a method that fires that modal window. My controller:
app.controller('AddProductController', ['$scope', 'ProductsService', '$uibModal', function ($scope, ProductsService, $uibModal) {
$scope.product = {};
$scope.searchCategories = function () {
ProductsService.getRootCategories().then(function (data) {
$scope.categories = data.data;
});
$scope.modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'categoryContent.html',
controller: 'AddProductController',
scope: $scope
});
$scope.modalInstance.result.then(function (category) {
$scope.searchCategory = null;
$scope.product.category = category;
}, function () {
});
};
$scope.ok = function(){
$scope.modalInstance.close($scope.product.category);
};
$scope.cancel = function(){
$scope.modalInstance.dismiss();
}]);
And my test:
describe("Products Controller", function () {
beforeEach(function () {
module('productsController');
});
beforeEach(function () {
var ProductsService, createController, scope, rootScope,
module(function ($provide) {
$provide.value('ProductsService', {
getRootCategories: function () {
return {
then: function (callback) {
return callback({data: {name: 'category1'}});
}
};
},
});
$provide.value('$uibModal', {
open : function(){
return {
then: function (callback) {
return callback({data: {name: 'category1'}});
}
};
}
});
return null;
});
});
describe('AddProductController', function () {
beforeEach(function () {
inject(function ($controller, _$rootScope_, _ProductsService_) {
rootScope = _$rootScope_;
scope = _$rootScope_.$new();
ProductsService = _ProductsService_;
createController = function () {
return $controller("AddProductController", {
$scope: scope,
});
};
});
});
it('calling searchCategories should make $scope.categories to be defined', function () {
createController();
expect(scope.categories).not.toBeDefined();
scope.searchCategories();
expect(scope.categories).toBeDefined();
});
});
});
All my tests pass,except this one, where I get TypeError: $scope.modalInstance.result is undefined.
Any clues?
It seems you're not defining result in your mock modal. Try something like this:
$provide.value('$uibModal', {
open: function () {
return {
result : {
then: function (callback) {
return callback({ data: { name: 'category1' } });
}
}
};
}
});
Here is the html:
<div class="col-lg-8" ng-controller="usersCtrl">
<scrollable height="180" ts-attach-spinner class="list-group">
</scrollable>
</div>
Here is the directive:
(function() {
'use strict';
angular
.module('angle')
.directive('tsAttachSpinner', tsAttachSpinner);
tsAttachSpinner.$inject = ['$window'];
function tsAttachSpinner($window) {
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
function spinnerOff() {
element.className = element.className + " whirl standard";
}
function spinnerOn() {
element.className = element.className.replace(" whirl standard", "");
}
scope.spin = function (promises) {
return $q.all(promises).then(function (eventArgs) {
spinnerOff();
});
}
}
}
})();
Here is the controller:
(function () {
'use strict';
angular
.module('angle')
.controller('usersCtrl', usersCtrl);
usersCtrl.$inject = ['$scope', 'usersSvc'];
function usersCtrl($scope, usersSvc) {
$scope.title = 'Users';
activate();
function activate() {
var promises = [getUsers()];
$scope.spin(promises);
}
function getUsers() {
return usersSvc.getUsers().then(function (data) {
return $scope.users = data;
});
}
}
})();
As you can see, I declare the spin function and attach it to the scope in the ts-attach-spinner directive. However, I am getting "undefined is not a function", when I call $scope.spin in the controller.
All advice appreciated, thanks in advance.
I'd like to call "myFunc()" inside my angular directive, how might I do this?
myApp.directive("test", function () {
return {
restrict: 'A',
template: "<div class='box'></div>",
myFunc: function() {
console.log('myFunc');
},
link: function ($scope, element, attrs) {
element.bind('click', function () {
myFunc(); //<------------- doesn't work
});
}
} // of return
});
You can't define the function as a property of your return value in your call to directive. It either needs to be defined before your return:
myApp.directive('test', function() {
var myFunc = function() {
console.log('myFunc');
};
return {
restrict: 'A',
template: '<div class="box"></div>',
link: function($scope, element, attrs) {
element.bind('click', myFunc);
}
};
};
Or the same way inside of your link function.
Just to play around :)
var app = angular.module('myApp', []);
app.controller('MainController',function() {
});
app.directive('one', function() {
return angular.extend({}, app.directive, {myfunct:function(){
alert('hello');
}});
});
app.directive('two', function(oneDirective) {
return {
link:function($scope,$element){
console.log(oneDirective[0].myfunct)
$element.on('click',oneDirective[0].myfunct);
}
};
});
or use the method binding "&":
app.directive('myDir', function() {
return {
scope: {
callback: "&"
},
link:function($scope,$element){
element.bind('click', function () {
$scope.evalAsync(function() {
$scope.callback({param1: value, param2: value2});
})
});
}
};
});
Usage:
<my-dir callback="myControllerMethod(param1, param2)"></my-dir>
I have a directive in which controller exists, where i have a function. I need to call that function from another controller.
Directive :
angular.module('test.directives').directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
$scope.getRoles = function() {
console.log('hi');
};
}
};
});
$scope.getRoles method is the method i need to call from different controller.
Controller:
angular.module("test.controllers").controller("testController", function($scope, $http) {
$scope.getUsers = function() {
// i need to call getRoles method here
}
});
How can i do that?
Please help,
Thanks.
You can use AngularJS Service/Factory
I put the getRoles function within the factory for the API which can be injected anywhere.
Working Demo
var RolesModule = angular.module('UserRoles', []);
RolesModule.factory('RolesAPI', function() {
return {
getRoles: function() {
this.roles = 'my roles';
console.log('test');
}
}
});
angular.module("test.controllers",['UserRoles'])
.controller("testController",function($scope,$rootScope,RolesAPI, $http) {
$scope.getUsers = function() {
RolesAPI.getRoles();
}
});
angular.module('test.directives',['UserRoles'])
.directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
}
};
})
Try following
angular.module('test.directives').directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
scope: {getRoles: '='},
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
$scope.getRoles = function() {
console.log('hi');
};
}
};
});
controller
angular.module("test.controllers").controller("testController", function($scope, $http) {
$scope.getUsers = function() {
// i need to call getRoles method here
$scope.getRoles()
}
});
in html
<manage-access get-roles="getRoles"></manage-access>
If the function is not dependent on the directive elements, move that to a service pass it to both directive and the testcontroller.
I have my custom angular service, which has one method that handles with $scope.$watch, is it possible to unit test it?
angular.module('moduleName', []).factory('$name', function () {
return {
bind: function ($scope, key) {
$scope.$watch(key, function (val) {
anotherMethod(key, val);
}, true);
},
...
};
});
Solution that I've found seems to be very easy and nice:
beforeEach(function () {
inject(function ($rootScope) {
scope = $rootScope.$new();
scope.$apply(function () {
scope.value = true;
});
$name.bind(scope, 'value');
scope.$apply(function () {
scope.value = false;
});
});
});
beforeEach(function () {
value = $name.get('value');
});
it('should have $scope value', function () {
expect(value).toBeFalsy();
});