7

I have some legacy jQuery code. It's a big chunk of code, so I would prefer to port it a little while later. To use it, I call $('#legacyId').legacyFunction().

Here's the deal, though.

I have an ng-if. And within that ng-if, I have the JavaScript where I call my legacy function.

<div ng-if="status=='yes'">
    <div id="legacyId">
        I am a legacy div!
    </div>
    <script type="text/javascript">
        $('#legacyId').legacyFunction()
    </script>
</div>

It looks like this JavaScript is being called when the page loads. Though I load angular after jQuery, it seems that angular removes the section under control of the ng-if, and therefore the jQuery function on #legacyId fails.

Any ideas? Thanks!


Edit-note: I import jQuery and the legacy code that extends jQuery at the top of my HTML document. Angular is loaded at the bottom of the document.


Edit-note 2: I have also tried <div ng-init="$('#legacyId').legacyFunction()"></div>, but I get an error, Error: [$rootScope:inprog] $apply already in progress.

7
  • Is this a typo? <div ng-if="status=='yes' (missing ")? Commented Nov 6, 2013 at 22:31
  • Yes, but no typo in actual source. Fixed. Commented Nov 6, 2013 at 22:31
  • Perhaps something with $scope.$watch could do the trick... Looking into it. Commented Nov 6, 2013 at 22:33
  • 3
    trying to lay angular over top jQuery DOM manipulation code is bad idea. Generally should work other way around, use angular first, then if need some DOM manipulation using jQuery, wrap it in a directive and call the jQuery from directive Commented Nov 6, 2013 at 22:37
  • Thanks charlieftl. Do you have any good examples? I do see, for example Combining AngularJS with existing Components. A bit more work than I want to dive into this moment, but could be a great resource a week or two from now. Commented Nov 6, 2013 at 22:38

1 Answer 1

6

Okay, managed to work this out.

In the HTML:

<div ng-if="status=='yes'">
    <div legacy-directive>
        I am a legacy div!
    </div>
</div>

In my app code:

app.directive('legacyDirective' , function() {
   return {
        link: function(scope, element, attrs) {
            $(element).legacyFunction(scope.$eval(attrs.legacyDirective));
        }
   }
});

Because of the $(element).legacyFunction(scope.$eval(attrs.legacyDirective));, it looks like I can also pass parameters to the legacyFunction; e.g. <div legacy-directive='{myParameter: true}>

Thank you for all who answered! You set me on the right track.

Sign up to request clarification or add additional context in comments.

1 Comment

if jQuery included in page before angular library, element is already a jQuery object, no need to wrap in $()

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.