Based on this example throbberDirective, How to inject custom directive to the controller, so that you can call the functions show() hide()? I can't get rid of the following error:
Error: [$injector:unpr] Unknown provider: inputThrobberProvider <- inputThrobber <- landingCtrl
Example code:
var app = angular.module('myapp', ['ngAnimate', 'ui.router', 'templates']);
app.directive('inputThrobber', [function() {
return {
restrict: 'A',
require: 'ngModel',
controller: function($scope, $element) {
var inputThrobberCtrl = {
show: function() {
$element.addClass('throbbing');
},
hide: function() {
$element.removeClass('throbbing');
}
};
return inputThrobberCtrl;
}
};
}])
.controller('landingCtrl', ['$scope', 'geolocation', 'inputThrobber', function($scope, geolocation, inputThrobber) {
// inputThrobber.show()
geolocation.getAddress().then(function(address) {
$scope.address = address;
}).catch(function(err) {
$scope.error = error;
$scope.address = '';
})
.finally(function() {
// $inputThrobber.hide()
});
}]);
Here's an example using that dispatches an event to show/hide the spinner:
app.directive('inputThrobber', [function() {
return {
restrict: 'A',
require: 'ngModel',
controller: function($scope, $element) {
$scope.$on('startThrobbing', function() {
$element.addClass('throbbing');
});
$scope.$on('stopThrobbing', function() {
$element.removeClass('throbbing');
});
}
};
}])
.controller('landingCtrl', ['$scope', 'geolocation', function($scope, geolocation) {
$scope.$broadcast('startThrobbing');
geolocation.getAddress().then(function(address) {
$scope.address = address;
}).catch(function(err) {
$scope.error = error;
$scope.address = '';
})
.finally(function() {
$scope.$broadcast('stopThrobbing');
});
}]);
Related
I am injecting a serivce into a directive and for some instance this service returns undefined can anyone explain what I am doing wrong?
Here is a plunker of the code below. https://plnkr.co/edit/H2x2z8ZW083NndFhiBvF?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.players = ["A","B","C"];
});
app.factory('PlayerListS', [function() {
var playerList = [];
function getList() {
return playerList;
}
function addToList(name) {
playerList.push(name);
}
return {
addToList :addToList,
getList: getList
}
}]);
app.directive("player",['PlayerListS', function (PlayerListS) {
return {
restrict: 'E',
scope: {
person:'#person',
add:'&add'
},
replace: false,
templateUrl: "player.html",
controller: function($scope, $element, $compile) {
$scope.add = function(name) {
PlayerListS.addToList(name);
console.log(PlayListS.getList());
}
}
};
}]);
You have a typo in your console because of which the code is throwing an error. Change your directive the following way
app.directive("player",['PlayerListS', function (PlayerListS) {
return {
restrict: 'E',
scope: {
person:'#person',
add:'&add'
},
replace: false,
templateUrl: "player.html",
controller: function($scope, $element, $compile) {
$scope.add = function(name) {
debugger;
PlayerListS.addToList(name);
console.log(PlayerListS.getList());
}
}
};
}]);
Working Demo: https://plnkr.co/edit/HhmOYyoZAhm6vvXp3puC?p=preview
When opening a bootstrap ui modal, if you prefer to use a directive, rather than separately a templateUrl and controller, how can you then in the controller of the directive for the modal, access $uibModalInstance in order to close the modal or whatever you need to do? Also, how can we pass items without having to add it as an attribute on the template?
angular.module('myModule', ['ui.bootstrap'])
.directive('myDirective', ['$timeout', function ($timeout) {
var controllerFn = ['$scope', '$uibModal', function ($scope, $uibModal) {
$scope.names = ['Mario','Wario','Luigi'];
$scope.openModal = function () {
var modalInstance = $uibModal.open({
animation: true,
template: '<my-modal>',
size: 'lg',
resolve: {
items: function () {
return $scope.names;
}
}
});
};
}];
return {
restrict: 'E',
templateUrl: '/Folder/my-directive.html',
controller: controllerFn,
scope: {
}
};
}])
.directive('myModal', ['$timeout', function ($timeout) {
var controllerFn = ['$scope', function ($scope) {
}];
return {
restrict: 'E',
templateUrl: '/Folder/my-modal.html',
controller: controllerFn,
scope: {
}
};
}]);
I use something like that to send parameter to modal, add an element to array and give it back to directive.
// Directive who open modal
.directive('myDirective', ['$timeout', function ($timeout) {
var controllerFn = ['$scope', '$uibModal', function ($scope, $uibModal) {
// Base array
$scope.names = ['Mario','Wario','Luigi'];
$scope.openModal = function () {
// Modal instance
var modalInstance = $uibModal.open({
animation: true,
template: '<my-modal>',
size: 'lg',
controller: 'myDirectiveModalCtrl',
controllerAs: '$modalController',
resolve: {
// Provide namesInModal as service to modal controller
namesInModal: function () {
return $scope.names;
}
}
});
// When modal close, fetch parameter given
modalInstance.result.then(function (namesFromModal) {
$scope.names = namesFromModal;
}, function () {
// $log.info('Modal dismissed at: ' + new Date());
});
};
}];
return {
restrict: 'E',
templateUrl: '/Folder/my-directive.html',
controller: controllerFn,
scope: {
}
};
}])
// Modal controller
.controller('myDirectiveModalCtrl', ['$uibModalInstance','namesInModal',
function ($uibModalInstance, namesInModal) {
// Use same name set in myDirective.controllerAs
var $modalController = this;
// Get provided parameter as service
$modalController.names = namesInModal;
// Add new element
$modalController.names.push('peach');
// Return modal variable when close
$modalController.ok = function () {
$uibModalInstance.close($modalController.names);
};
$modalController.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
]);
In the directive's link function, $uibModalInstance is available on the scope object.
I want to call alertForm directive in loginForm directive. Where I want call 'alertForm' directive in 'loginForm' is highlighted as //i want to call here
alertForm directive
angular.module('myApp')
.directive('alertForm', function () {
return {
templateUrl: 'app/directives/alert/alertForm.html',
restrict: 'E',
scope: {
topic: '=topic',
description: '=description'
},
controller: function($scope) {
$scope.words = [];
this.showAlert = function() {
$scope.description.push("hello");
};
}
};
});
loginForm directive
angular.module('myApp')
.directive('loginForm', function() {
return {
templateUrl: 'app/directives/loginForm/loginForm.html',
restrict: 'E',
scope: {
successCallback: '&',
errorCallback: '&',
emailField: '='
},
link: function (scope, element, attrs) {
},
controller: function ($rootScope, $scope, authenticationService) {
$scope.loginFormData = {};
$scope.inProgress = false;
$scope.onLogin = function (form) {
if (form.$valid) {
$scope.inProgress = true;
authenticationService.loginUser('password', $scope.loginFormData).then(function () {
$scope.successCallback({formData: $scope.loginFormData});
}, function (err) {
$scope.inProgress = false;
if (err.message) {
**// i want to call here**
}
});
}
}
}
};
});
You can use require config of directive.
When a directive requires a controller, it receives that controller as
the fourth argument of its link function. Ref : Documentation
You can implement this in your code
angular.module(‘myApp')
.directive('loginForm', function() {
return {
templateUrl: 'app/directives/loginForm/loginForm.html',
restrict: 'E',
require:'alertForm',
scope: {
successCallback: '&',
errorCallback: '&',
emailField: '='
},
link: function (scope, element, attrs, alertFormCtrl) {
scope.alertFormCtrl = alertFormCtrl;
},
controller: function ($rootScope, $scope, authenticationService) {
$scope.loginFormData = {};
$scope.inProgress = false;
$scope.onLogin = function (form) {
if (form.$valid) {
$scope.inProgress = true;
authenticationService.loginUser('password', $scope.loginFormData).then(function () {
$scope.successCallback({formData: $scope.loginFormData});
}, function (err) {
$scope.inProgress = false;
if (err.message) {
// Calling showAlert function of alertFormCtrl
$scope.alertFormCtrl.showAlert();
}
});
}
}
}
};
});
Add the following line in the app/directives/loginForm/loginForm.html :
<alertForm topic="something" description = "something" ng-if="showAlert"></alertForm>
Now inside the loginForm directive's controller : // i want to call here
use
$scope.showAlert = true;
Note: you can use some variable to setup the topic and description as well inside the alertForm.
Unknown provider: $confirmModalProvider <- $confirmModal <- confirmModalCtrl
Why am I getting this error? I'm trying to use AngularJS UI Bootstrap to open a modal and get the result. I get this error when I trigger $scope.deleteQuestion(). Any idea what I'd doing wrong here?
var crtPromoCtrl = angular.module('crtPromoCtrl', ['crtPromoSrv']);
crtPromoCtrl.controller('surveyCtrl', ['$scope', '$modal', 'surveySrv', function($scope, $modal, surveySrv)
{
$scope.questions = surveySrv.getQuestions();
$scope.editQuestion = function(index)
{
surveySrv.setEditQuestion(index);
};
$scope.deleteQuestion = function(index)
{
var confirmModal = $modal.open({
templateUrl: 'confirm-delete.html',
controller: 'confirmModalCtrl',
size: 'sm'
});
confirmModal.result.then(function(msg)
{
console.log(msg);
});
return false;
};
}]);
crtPromoCtrl.controller('confirmModalCtrl', ['$scope', '$confirmModal', function($scope, $confirmModal)
{
$scope.yes = function()
{
$confirmModal.close('yes');
};
$scope.no = function()
{
$confirmModal.dismiss('no');
};
}]);
EDIT: https://angular-ui.github.io/bootstrap/#/modal
You second controller should use $modalInstance instead of $confirmModal
Please note that $modalInstance represents a modal window (instance)
dependency.
Code
crtPromoCtrl.controller('confirmModalCtrl', ['$scope', '$modalInstance', function($scope, $modalInstance) {
$scope.yes = function() {
$modalInstance.close('yes');
};
$scope.no = function() {
$modalInstance.dismiss('no');
};
}]);
I can pass strings and objects, but for some reason when I add callback functions to my scope object that I'm using as configurable options, Angular strips them out.
HTML:
<div ng-controller="DemoCtrl">
scope.options = {{ options }}
<br><br>
<div my-directive="{{ options }}"></div>
</div>
JS:
var app = angular.module('demo2', []);
app.controller('DemoCtrl', function($scope) {
$scope.options = {
test_str: 'test',
init_cb: function() {
alert('custom init callback');
},
apply_cb: function() {
alert('custom apply callback');
}
};
});
app.directive('myDirective', ['$parse', function($parse) {
function link(scope, element, attrs) {
var options = attrs.myDirective;
scope.init(options);
}
return {
restrict: 'A',
transclude: true,
link: link,
controller: ['$scope', function($scope) {
$scope.defaults = {
init_cb: function() {
alert('default init callback');
},
apply_cb: function() {
alert('default apply callback');
}
};
$scope.settings = {};
$scope.init = function(options) {
$scope.settings = $.extend({}, $scope.defaults, $scope.options);
// init cb.
$scope.settings.init_cb();
// apply cb.
$scope.settings.apply_cb();
};
}]
};
}]);
Here is a fiddle: http://jsfiddle.net/revolunet/pHZNY/
Thanks for your help.
You are trying to use the attr, which can only be a string, when you need to just pass the actual variable into the scope:
var app = angular.module('demo2', []);
app.controller('DemoCtrl', function($scope) {
$scope.options = {
test_str: 'test',
init_cb: function() {
alert('custom init callback');
},
apply_cb: function() {
alert('custom apply callback');
}
};
});
app.directive('myDirective', ['$parse', function($parse) {
return {
restrict: 'A',
transclude: true,
scope: { //use scope to pass in variables
options: '=myDirective'
},
controller: ['$scope', function($scope) {
$scope.defaults = {
init_cb: function() {
alert('default init callback');
},
apply_cb: function() {
alert('default apply callback');
}
};
$scope.settings = {};
$scope.init = function(options) {
$scope.settings = angular.extend({}, $scope.defaults, $scope.options);
// init cb.
$scope.settings.init_cb();
// apply cb.
$scope.settings.apply_cb();
}();
}]
};
}]);