7

I am rewriting a jQuery application to using AngularJS. I am using small steps, and replacing one area at a time. I am however having issues on how I can listen to jQuery's events in AngularJS.

As an example I have a $(document).trigger('doSomething') in a jQuery Widget. How can I listen to it in a AngularJS controller?

I have tried using $scope.$on('doSomething', function(){}), but that only refers to the scope of the controller. I also tried with $rootScope.$on('doSomething', function(){}), but without luck.

Is there any way where I step by step can convert my application, and just listen to the document events triggered by jQuery?

4 Answers 4

6

I'm firing from the hip here, but I think jQuery events and AngularJS events are two separate systems. A quick solution might be to have a global catch-all jQuery event listener which translates the jQuery event into an AngularJS event.

Later on you might want two wrap the widget in a directive and put a more specific event-translator inside it. At that point you could also consider if you want to stick to the event-system or if an angular service might be a more suitable way for the widget to communicate with the rest of the world.

The above assumes you can't or don't want to rewrite the widget to use AngularJS mechanisms. If that's an option then just use $scope.$broadcast or $scope.$emit directly in the widget instead of $.trigger.

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

1 Comment

I would love to convert the widget to AngularJS, but it isn't so easy. I am using jpanelmenu.com (which then broadcasts events), which would be hard to translate to AngularJS.
1

You should see this answer: https://stackoverflow.com/a/15012542/535025

I am not sure, but i think you can't do that. Like @Supr said, they are two separated systems with separated custom events.

Try not to mix jQuery with Angular. A good recomendation is that every time you need to call $('selector').method() consider to write a directive, because it take care of the data binding.

1 Comment

No, it doesn't. You would have to take care of that anyway inside a controller.
0

Here is my solution: We need to emit "click" event with jQuery after all XHR data is ready, before that we can transfer new data via html data-attribute, later we can read it from Angular.

Html file

<div class="js-synced-tabs" ng-click="syncWithjQuery()" data-tab-id="1" style="width: 0; height: 0;"></div>
<div class="container" id="draggable-status-list">
<!-- appends from jQuery -->
</div>

jQuery file

httpRequest('GET', 'API/point' , function (data) ....
$.each(data, function (i, v) {
html += '<a onclick="'+"jQuery('.js-synced-tabs').data('tab-id',"+ v.id +"); jQuery('.js-synced-tabs').click();"+'">' 
        + v.name
        + '</a>';
$('body').find('.container').html(html);
})

Angular file

$scope.syncWithjQuery = function() {
  $rootScope.issue_tab = angular.element('.js-synced-tabs').data('tab-id');
}

Example showing changing data-tab-id, after clicking on selected tab, because we cannot do it through ng-click.

onclick="'+"jQuery('.js-synced-tabs').data('tab-id',"+ v.id +"); jQuery('.js-synced-tabs').click();"+'" - is hack for this

Gist: https://gist.github.com/cre-o/f138bdf1cf9e36eed3f9f73b54bb8260

Comments

0

You could fire an Angular event from within the jQuery event, and capture this other event in Angular, like this:

$( "p" ).on( "click", function() {
    // I'm not sure if you'd need to run code below inside $scope.$apply
    
    // $broadcast will send the event downwards the $scope hierarchy, while $emit will send it upwards
    $scope.$broadcast('jquery-click');
});

And later on somewhere in your code:

$scope.$on('jquery-click', function() {
    // desired code in Angular's scope
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.