Search code examples
angularjsmagnific-popup

Angular JS ng-click inside a modal window / Refresh angular scope in modal callback


I'm loading a modal window into my html using magnific popup, which is essentially doing this:

<html ng-app='basket'>
    <body ng-controller='BasketController as basket'>

        <a id='open' href='/product/1'>Open modal</a>
        <a ng-click='addToCart(1)'>Add to cart</a>
    </body>
</html>

... After Ajax load

<html ng-app='basket'>
    <body ng-controller='BasketController as basket'>

        <div class='modal>
            <h1>Product title</h1>
            <a ng-click='addToCart(1)'>Add to cart</a>
        </div>

        <a id='open' href='/product/1'>Open modal</a>
        <a ng-click='addToCart(1)'>Add to cart</a>
    </body>
</html>

But the ng-click inside the modal doesn't fire. Is there a way I can refresh the scope with the modal content included?

To begin with, I thought I'd give it a go by adding an ng-click to the open modal button that can pass the scope to another function that opens the modal. I have a function that can console log the $scope after it has loaded, but I just need to refresh or something to make angular recognise the new html in the modal window.


Solution

  • The reason this doesn't work is because angularJS is not aware of the ng-click inside the modal. It was added by jQuery by the looks of it. AngularJS has not processed that HTMl and the ng-click does nothing.

    You can, however, potentially use the $compile function in AngularJS to $compile the modal HTML with a particular scope. Then, the ng-click will work.

    Have a read about $compile here:

    https://docs.angularjs.org/api/ng/service/$compile

    So an example in your case might be:

    $compile(modalElement)($scope);
    

    Where this happens inside BasketController, so that would be BasketController passed in to manage modalElement - the raw DOM element, not the jQuery element.

    So at some point if you have access to the modal html (just after load) you could do that. Not recommended at all though! Use an Angular library.