In controller I get some JSON data using $http or $resource services. Then I write this data in $scope and AngularJS updates HTML structure of the page. My problem is that I need to know what is the new size (width and height) of the list (I mean, HTML DOM element) that is filled with Angular ng-repeat
directive. Consequently, I have to run javascript code right after Angular finishes updating DOM structure. What is the proper way to do it? I have searched internet over the last four hours but I couldn't find any solution to my problem.
This is how I receive JSON data:
var tradesInfo = TradesInfo.get({}, function(data){ console.log(data); $scope.source.profile = data.profile; $scope.trades = $scope.source.profile.trades; $scope.activetrade = $scope.trades[0]; $scope.ready = true; init(); //I need to call this function after update is complete });
And this is what happens in init()
function:
function init(){ alert($('#wrapper').width()); alert($('#wrapper').height()); }
I know that there must be something easy to solve this problem but I can't just find it now. Thanks in advance.
Does AngularJS use the jQuery library? Yes, AngularJS can use jQuery if it's present in your app when the application is being bootstrapped. If jQuery is not present in your script path, AngularJS falls back to its own implementation of the subset of jQuery that we call jQLite.
Adding jQuery to AngularYou need to create an Angular application using ng new command and then you need to 'cd' into that folder to install jQuery via NPM in the development environment.
We have recently found out that the development team has build this functionality by using jQuery instead of Angular. From what I have researched so far, using jQuery in an Angular platform is bad practice and can make the platform more complicated for management and updates.
Whereas, Angular is designed to handle large-size projects that have high complexity. jQuery is easier to understand than Angular that is said to have a learning curve. Everything from DOM manipulation, Ajax calls, to delegating events and adding elements, jQuery makes it quite easy to get a handle on.
Actually in this case the angular way is not the easy way but the only right way :)
You have to write a directive and attach to the element you want to know the height of. And from the controller you $broadcast an event, the directive'll catch the event and there you can do the DOM manipulation. NEVER in the controller.
var tradesInfo = TradesInfo.get({}, function(data){ console.log(data); $scope.source.profile = data.profile; ... $scope.$broadcast('dataloaded'); }); directive('heightStuff', ['$timeout', function ($timeout) { return { link: function ($scope, element, attrs) { $scope.$on('dataloaded', function () { $timeout(function () { // You might need this timeout to be sure its run after DOM render. element.width() element.height() }, 0, false); }) } }; }]);
Olivér's answer is good, but has an issue: if you forget to broadcast the event, your javascript will not run whereas your data might have changed. Another solution would be to watch for changes on the scope, for instance:
var tradesInfo = TradesInfo.get({}, function(data) { console.log(data); $scope.profile = data.profile; // ... }); directive('heightStuff', ['$timeout', function($timeout) { return { scope: { myData: '=' }, link: function($scope, element, attrs) { $scope.$watch('myData', function() { $timeout(function() { // You might need this timeout to be sure its run after DOM render. element.width() element.height() }, 0, false); }) } }; } ]);
<div height-stuff my-data="profile"></div>
This way the javascript functions are called every time the data changes without any need for a custom event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With