3

Our teams have inherited a jQuery Mobile project from another office and now we are trying to implement new features using AngularJS. The idea is also to migrate the whole jQuery website to AngularJS, step by step. Ideally, we would star the project from scratch in AngularJS, but that's not feasible for the time being.

The thing is, we have a jQuery tabs control which loads its tabs content via AJAX. All the current tabs are jQuery and we need to implement a new one, wrapping AngularJS code around it. But this is not working...

I've created a simple example to demonstrate the problem.

The live example can be found here:

http://ricardoamaral.net/jquery/

Click the "Ajax Loaded" tab and see for yourself that the Angular variable is not updated with the value defined in the Angular controller.

The following is code from the example above:

index.html

<!doctype html>
<html lang="en" ng-app="ngSampleApp">
    <head>
        <meta charset="utf-8">
        <title>jQuery UI Tabs</title>

        <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">

        <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
        <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>


    </head>
    <body>
        <div id="tabs">
            <ul>
                <li><a href="#tabs-1">Preloaded</a></li>
                <li><a href="ajax.html">Ajax Loaded</a></li>
            </ul>
            <div id="tabs-1" ng-controller="sampleController">
                <p>Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.</p>
            </div>
        </div>
    </body>
</html>

Script:

<script>
    $(function() {
        $("#tabs").tabs();
    });

    var app = angular.module('ngSampleApp', []);

    app.controller("sampleController", ['$scope', function($scope) {
        $scope.demoText = "Hello World!"
    }]);
</script>

ajax.html

<p><strong>This content was loaded via ajax.</strong></p>
<p>{{demoText}}</p>
8
  • I'd suggest you create a directive for the jquery part. Commented Dec 12, 2013 at 13:18
  • this isn't related to jQuery-Mobile. Commented Dec 12, 2013 at 13:21
  • @lucuma That would require a lot of refactoring. Which we will be doing in the form of getting rid of jQuery to Angular. We are looking for an "easier" solution to workaround the problem in the mean time. Commented Dec 12, 2013 at 13:35
  • @Omar Sorry, removed the tag. Commented Dec 12, 2013 at 13:37
  • 1
    creating a directive for your issue is the easier way of addressing it. Commented Dec 12, 2013 at 14:09

1 Answer 1

3

The problem you have importing templates with angular expressions is angular is not aware of the new content in DOM. Whenever you insert html from outside angular, you need to use $compile so that angular can process all expressions and directives ( including the ng-directives)`

Here's a very simple example of integrating jQueryyUI tabs into a directive to make your demo do what you expect

HTML

<div id="tabs" jq-tabs>

JS

app.directive('jqTabs', function($compile, $timeout) {
  return function(scope, elem, attrs) {
    elem.tabs({/* initalize UI tabs*/
      /* using jQueryUI tabs API, compile angular content in load event callback*/
      load: function(event, ui) {
        $timeout(function() {
          $compile($(ui.panel).contents())(scope)
        });
      }

    });
  }
})

DEMO

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

4 Comments

Is the $timeout really necessary since the timeout value is 0?
delays digest... need a chance for new content to render. Did you try it without it?
It doesn't work without it... What if the timeout returns and the content has not been loaded yet?
why would that happen? I think you need to read up on angular digest cycles

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.