Cyrille Cyrille - 1 year ago 76
AngularJS Question

Call a function on click on a transcluded element inside an AngularJS directive

I wrote a modal directive because I want to have a couple of modal on a page. I used this tutorial to achieve this :

To begin, here is my directive code, which is pretty the same as the one in the previous tutorial :

//here, app is an AngularJS module
app.directive('modal', function() {
return {
restrict: 'E',
scope: {
show: '='
replace: true,
transclude: true,
link: function(scope) {
scope.hide = function() { = false;
template: '<div class="Modal" ng-show="show"><div class="Modal-overlay" ng-click="hide()"></div><button class="Modal-close" ng-click="hide()"></button><div class="Modal-content" ng-transclude></div></div>'

Then here is how I use it :

<modal show="showInformationsModal">
<h2 class="Modal-title">Informations</h2>
<button type="button">Close this</button>

What I want to achieve is being able to close the modal (ie. call the
function defined in the directive's scope). But I can't put the button in the template of my directive because sometimes I want a button in the modal to close it, but sometimes not, and the text inside this button will never be the same.

I tried some things like :

  • <button type="button" ng-click="hide()">Close this</button>

  • <button type="button" ng-click="showInformationsModal = false">Close this</button>

  • <button type="button" ng-click="show = false">Close this</button>

Nothing worked. I think I'm missing something ! Can somebody help me ?

Thank you,


Answer Source


As it was pointed out in this comment, the transclude function can be more generic by replacing var contentElement = element[0].querySelector('.Modal-content'); with var contentElement = element[0].querySelector('[ng-transclude]');


A friend sent me this link :

What I was missing is precisely what this link is pointing out : transcluded HTML's scope is not directive's isolated scope.

I used the fifth parameter of the link function :

transclude(scope, function(clone, scope) {
  var contentElement = element[0].querySelector('.Modal-content');
  contentElement.innerHTML = '';

  for (var i = 0; i < clone.length; ++i) {

Here is the codepen updated. I don't know if it's the most beautiful way to solve my problem, but it solves it !

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download