Ng-click stops working after the first use of $ compilation when using nested directives

I have a modular Angular directive that uses the helper / wrapper directive. That way, I can always use the same shell and just load another template where it is needed for other modal content.

PROBLEM: This snippet works, but only for the first modal life cycle. So I can start modal, close modal and run it again. But as soon as the modal function is opened a second time, none of the ng-click directives work. Any advice would be just super.

Using

<button my-modal="views/login.html">Launch Login-specific Modal</button> 

Directory Module (app.js)

 angular.module('myModal',[]) .directive('modalWrapper', function(){ return { replace: true, templateUrl: 'views/modal.html', controller: function($scope, $element){ $scope.close = function(){ $element.remove(); }; // NOTE: I use this array to showcase that ng-repeat still works the second time although ng-click stops functioning properly. $scope.others = ["One", "Two", "Three"]; } } }) .directive('myModal', function( $compile){ function link(scope, element, attr){ scope.partial = attr.myModal; // NOTE: Loads sub template via ng-include var ngModal = $compile('<div modal-wrapper></div>')(scope); element.on('click', function(){ angular.element('body').append(ngModal); }); scope.yo = function(){ alert("Yo from inside template."); }; } return { link: link, scope: {} } }); 

Patterns

modal.html

 <div class="my-modal"> <p>Modal Wrapper</p> <div ng-include="partial"></div> <button ng-click="close()">Close</button> <p>This just proves that other directives still work (ng-repeat), but ng-click does not.</p> <div ng-repeat="stuff in others"> <p>{{stuff}}</p> </div> </div> 

login.html

 <h1>Well hey there, I'm the login template.</h1> <button ng-click="yo()">Say Yo</button> 
+7
angularjs angularjs-directive
source share
1 answer

I think the problem is that you are destroying the area where ng-click is compiled.

When scope.close() is called, $element.remove() appears. This removes the element from the DOM, and destroys the area to which it is attached. This will cause your ng-click be canceled.

Unfortunately (as of the last time I checked), element.detach() also destroys the scope, so it is best to compile and add an element to the body only once. After that, you can use element.show() and element.hide() to show and hide the modal. Alternatively, you can recompile the modal every time you want to show it.

+5
source share

All Articles