I am using Angular's $uibModal and trying to create popup while page has been loaded. It is not working. I think problem in directive. This is my code:
angular.module('myModule', ['ui.bootstrap'])
.directive('modalPop', ModalDirective)
.controller('ModalController', ModalController);
function ModalDirective($uibModal) {
return {
scope: {},
restrict: 'E',
templateUrl: 'directives/modal/tutorial.html',
controller: function () {
return $uibModal.open({
controller: 'ModalController',
windowClass: 'outside ' + size,
animation: true,
templateUrl: './client/dialogs/' + template + '.html',
resolve: {
dialogParams: function () {
return {
title: 'title',
message: 'message'
};
}
}
});
}
};
}
function ModalController($uibModalInstance) {
$scope.close = function () {
$uibModalInstance.dismiss();
};
}
How can I get this to work?
You are not injecting the provider into the directive's controller. Also try explicitly injecting the provider into the directive:
ModalDirective.$inject = ['$uibModal'];
function ModalDirective($uibModal) {
return {
scope: {},
restrict: 'E',
templateUrl: 'directives/modal/tutorial.html',
controller: function ($uibModal) {
return $uibModal.open({
controller: 'ModalController',
windowClass: 'outside ' + size,
animation: true,
templateUrl: './client/dialogs/' + template + '.html',
resolve: {
dialogParams: function () {
return {
title: 'title',
message: 'message'
};
}
}
});
}
};
}
If that doesn't work, then you have not properly included the JS file for Angular UI Bootstrap. (This is most likely the cause)
Related
I have a directive Foo in Directive Bar i am trying to call a function in Foo
but it is not working.
http://jsfiddle.net/4d9Lfo95/3/
example fiddle is created.
angular.module('ui', []).directive('uiFoo',
function() {
return {
restrict: 'E',
template: '<p>Foo</p>',
link: function($scope, element, attrs) {
$scope.message = function() {
alert(1);
};
},
controller: function($scope) {
this.message = function() {
alert("Foo Function!");
}
}
};
}
).directive('uiBar',
function() {
return {
restrict: 'E',
template: '<button ng-click="callFunction()">Bar</button> <ui-foo></ui-foo>',
require: 'uiFoo',
scope: true,
link: function($scope, element, attrs, uiFooController) {
$scope.callFunction = function() {
alert('Bar Function');
uiFooController.message();
}
}
};
}
);angular.module('myApp', ['ui']);
where as the UI looks like this
<div ng-app="myApp"> <ui-bar> </ui-bar></div>
You left out this error message:
Controller 'uiFoo', required by directive 'uiBar', can't be found!
The problem is that the require hierarchy searches up the tree, not down it. So, ui-bar is trying to find a uiFoo directive controller either on itself or (with the ^ symbol) in one of it's ancestors, not one of it's children.
If you want to call a method from the child directive, just use the scope: http://jsfiddle.net/4d9Lfo95/5/
angular.module('ui', []).directive('uiFoo',
function() {
return {
restrict: 'E',
template: '<p>Foo</p>',
controller: function($scope) {
$scope.message = function() {
alert("Foo Function!");
}
}
};
}
).directive('uiBar',
function() {
return {
restrict: 'E',
template: '<button ng-click="callFunction()">Bar</button> <ui-foo></ui-foo>',
scope: true,
controller: function($scope) {
$scope.callFunction = function() {
alert('Bar Function');
$scope.message();
}
}
};
}
);
I can not access the vm.screensize property from the relevant controller. The error I am receiving is the vm is not defined. Below are the directive and controller.
angular.module('app.ain.directives')
.directive('ainProjectWizardExplanations', function() {
return {
restrict: 'E',
bindToController: true,
scope : {
sidenavHidden : '='
},
controller: 'ProjectWizardExplanationsController as vm',
templateUrl: function() {
console.log(vm.screensize, vm.animate);
if(vm.screensize) {
return 'app/ain/shared/directives/projectWizardExplanationsMobile.html';
}else {
return 'app/ain/shared/directives/projectWizardExplanations.html';
}
}
};
});
//controller
angular
.module('app.ain.directives')
.controller('ProjectWizardExplanationsController', ProjectWizardExplanationsController);
function ProjectWizardExplanationsController($mdMedia,$scope,$rootScope, $timeout) {
var vm = this;
vm.animate = true;
$scope.$watch(function() { return $mdMedia('sm'); }, function(small) {
vm.screensize = small;
});
}
Try setting the "controllerAs" option when declaring the directive instead.
.directive('ainProjectWizardExplanations', function() {
return {
restrict: 'E',
bindToController: true,
scope : {
sidenavHidden : '='
},
controller: 'ProjectWizardExplanationsController',
controllerAs: 'vm',
templateUrl: function() {
console.log(vm.screensize, vm.animate);
if(vm.screensize) {
return 'app/ain/shared/directives/projectWizardExplanationsMobile.html';
}else {
return 'app/ain/shared/directives/projectWizardExplanations.html';
}
}
};
});
Hope that works for you :)
I have started to use directives with ui-router:
$stateProvider
.state('book', {
abstract: true,
url: '/:book',
template: '<book-tabs />'
})
.state('book.about', {
url: '',
template: '<book-about />'
})
.state('book.stats', {
url: '/statistics',
template: '<book-stats />'
});
Here is one of the directives:
export default function(app) {
app.directive('bookStats', function() {
return {
restrict: 'E',
controllerAs: 'statsTab',
templateUrl: 'book-stats.tpl.html',
controller: 'BookStatsCtrl'
};
});
};
Inside of book-stats directive I want to call stats-list directive and pass book object.
<stats-list review="statsTab.book"></stats-list>
And here is stats-list directive:
export default function(app) {
app.directive('statsList', function() {
return {
restrict: 'E',
scope: {
book: '='
},
templateUrl: 'stats-list.tpl.html',
controller: 'CircleRankListCtrl'
};
});
};
The problem is that $scope.book is undefined in stats-list directive even though that statsTab.book not undefined in book-stats directive.
What am I doing wrong?
Controller 'alertForm', required by directive 'loginForm', can't be
found!
angular.module('jobsApp')
.directive('alertForm', function () {
return {
templateUrl: 'app/directives/alert/alertForm.html',
restrict: 'E',
scope: {
topic: '=topic',
description: '=description'
}
}
})
.directive('loginForm', function() {
return {
templateUrl: 'app/directives/loginForm/loginForm.html',
restrict: 'E',
require: '^alertForm',
scope: {
successCallback: '&',
errorCallback: '&',
emailField: '='
},
link: function (scope, element, attrs, alertFormModelCtrl) {
scope.alertFormModel = alertFormModel
},
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.inProgress = false;
}, function (err) {
$scope.inProgress = false;
if (err.message) {
//$scope.alertFormCtrl.topic = "asdffasfd";
alert(err.message);
}
});
}
}
}
};
});
Your directive requires the alertForm controller to be present in the scope of the loginForm. You'll either have to add it to the current scope. Or prefix the requirement with a ^ to search in the parent scope.
From https://docs.angularjs.org/guide/directive:
The myPane directive has a require option with value ^myTabs. When a directive uses this option, $compile will throw an error unless the specified controller is found. The ^ prefix means that this directive searches for the controller on its parents (without the ^ prefix, the directive would look for the controller on just its own element).
How to access directive controller functions from directive link? Bellow controller passed to link is empty, I would like to get in it show() hide() functions.
My current directive:
app.directive('showLoading', function() {
return {
restrict: 'A',
// require: 'ngModel',
scope: {
loading: '=showLoading'
},
controller: function($scope, $element) {
return {
show: function() {
alert("show");
},
hide: function() {
alert("hide");
}
};
},
link: function($scope, $element, $attrs, controller) {
$scope.$watch('loading', function(bool) {
if (bool) {
controller.show();//undefined
} else {
controller.hide();
}
});
}
};
});
Publishing on the scope can work, but not the best practice, since it "pollutes" the scope. The proper way to communicate with own controller is to require it - then it will become available as a parameter to the link function, along with other required directives.
The other issue is with how you expose functions on the controller - this is done by using this.someFn, not by returning an object.
app.directive('showLoading', function() {
return {
restrict: 'A',
require: ['ngModel', 'showLoading'], // multiple "requires" for illustration
scope: {
loading: '=showLoading'
},
controller: function($scope, $element) {
this.show = function() {
alert("show");
};
this.hide = function() {
alert("hide");
};
},
link: function($scope, $element, $attrs, ctrls) {
var ngModel = ctrls[0], me = ctrls[1];
$scope.$watch('loading', function(bool) {
if (bool) {
me.show();
} else {
me.hide();
}
});
}
};
});
You have some kind of problem inside of controller function
Here is code working fine
app.directive('showLoading', function() {
return {
restrict: 'AE',
// require: 'ngModel',
scope: {
loading: '=showLoading'
},
controller: function($scope, $element) {
$scope.show = function() {
alert("show");
},
$scope.hide = function() {
alert("hide");
}
},
link: function($scope, $element, $attrs) {
$scope.$watch('loading', function(bool) {
if (bool) {
$scope.show();//undefined
} else {
$scope.hide();
}
});
}
};
});