简体   繁体   中英

AngularJS controller called before jquery document ready callback

I have two Angular 1.x controllers and an external open source library with gets initialized on document ready as follows,

 $(function () {
    $.support.x = 10;
 });

So the ordering in which I load the JS files are 1. Angular framework 2. This external OS library 3. My AngularJS controllers

Once I load the page, the document.ready(jquery) of open source library is not getting called first, rather control is going to AngularJS controller constructors first. After the controller execution is complete, then only document.ready(jquery) is called.

I have simplified the context here, but I have other javascript files as well before my controllers. The doubts which I have are,

  1. Why is the controller getting loaded first ?
  2. Is it to do with the ordering of my JS files ?
  3. AngularJS loads first irrespective of other document.ready(jquery) methods in other JS libraries ?

Thanks in advance.

From the docs :

AngularJS initializes automatically upon DOMContentLoaded event or when the angular.js script is evaluated if at that time document.readyState is set to complete .

So:

1) I think that's because the angular.js script goes earlier of any $(document).ready(function(){}); handlers and angularjs starts bootstrapping before this handlers are fired;

2) Yes. Take a look at this two examples (the difference is only in the angular.js script placement):

 angular.module('myApp', []) .controller('MyCtrl', ['$scope', '$timeout', function MyCtrl($scope, $timeout) { var ctrl = this; console.log('ctrl'); return ctrl; }]); 
 <div ng-app="myApp"> <div ng-controller="MyCtrl as $ctrl"> </div> </div> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script> $(document).ready(function(){ console.log('doc'); }); </script> <script src="//code.angularjs.org/1.6.2/angular.js"></script> 

and:

 angular.module('myApp', []) .controller('MyCtrl', ['$scope', '$timeout', function MyCtrl($scope, $timeout) { var ctrl = this; console.log('ctrl'); return ctrl; }]); 
 <div ng-app="myApp"> <div ng-controller="MyCtrl as $ctrl"> </div> </div> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//code.angularjs.org/1.6.2/angular.js"></script> <script> $(document).ready(function(){ console.log('doc'); }); </script> 

For the first one the output will be doc-ctrl and for the second one ctrl-doc .

3) By default it loads as described in the quote. But you can use manual initialization to control the process. No matter when the angular.js script is included, the order of output will be doc - stuff.loaded -> do bootstrap - ctrl

 angular.module('myApp', []) .controller('MyCtrl', ['$scope', '$timeout', function MyCtrl($scope, $timeout) { var ctrl = this; console.log('ctrl'); return ctrl; }]); 
 <div> <div ng-controller="MyCtrl as $ctrl"> </div> </div> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="//code.angularjs.org/1.6.2/angular.js"></script> <script> $(document).on('stuff.loaded', function(){ console.log("stuff.loaded -> do bootstrap"); //manually bootstrap angularjs app angular.element(function() { angular.bootstrap(document, ['myApp']); }); }); </script> <script> $(document).ready(function(){ console.log('doc'); //some your stuff here //... $(document).trigger('stuff.loaded'); }); </script> 

Are you using ng-app? If so you could bootstrap angular manual and remove the ng-app

document.ready(function{
    angular.bootstrap(document, ['myApp']);
})

Then angular will run after dom is ready angular bootstrap

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM