Cyrille Cyrille - 3 months ago 15
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 : http://adamalbrecht.com/2013/12/12/creating-a-simple-modal-dialog-directive-in-angular-js/

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() {
scope.show = false;
document.body.classList.remove('wwf-noScroll');
};
},
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>
</modal>


What I want to achieve is being able to close the modal (ie. call the
hide
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,

Cyrille

Answer

EDIT

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]');

ORIGINAL

A friend sent me this link : http://angular-tips.com/blog/2014/03/transclusion-and-scopes/

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) {
    contentElement.appendChild(clone[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 ! http://codepen.io/JesmoDrazik/pen/NqZLYR?editors=001

Comments