0

Recently I started making my own application on AngularJS. At the early stages I faced a problem and I haven't been able to solve it for quite a long time. In my app I use ng-view and angular-route to load different parts from .html files. In most of them I require third-party libraries, like Loading Bar. I add script src in the end of body. The thing is, like with that Loading Bar, if I use it OUTSIDE ng-view in index.html it works perfectly fine. But if I put elements which require this library in other .html files and are then loaded into ng-view the script does not work. Here's the example:

<body>

<div ng-view></div>
<div
        class="ldBar label-center"
        style="width:50%;height:50%;margin:auto"
        data-value="35"
        data-preset="circle"
></div>

<script src="libs/loading-bar/loading-bar.js"></script>
</body>

This code works as intended. But if I load the code via ng-view like this:

<div ng-view>
<div
            class="ldBar label-center"
            style="width:50%;height:50%;margin:auto"
            data-value="35"
            data-preset="circle"
    ></div>
</div>

It doesn't work. As far as I understand it, I need to initialize the library script AFTER the ng-view loads. Or maybe the problem is somewhere else. There are a lot of similar questions here, but the answers are not entirely clear to me. Most of them are about creating custom factory or service. But how am I supposed to do it with a third-party library? If it's possible, I would be grateful if someone would show me how exactly solve this problem using the same Loading Bar. Thank you.

  • 1
    Keep it outside ng-view or put it in view templates. ng-view gets emptied every time a route initializes and then populated with the new route template – charlietfl Jan 06 '18 at 23:38
  • When people are suggesting making factories/services or directives to wrap third party things it's because that makes them easy to access and use in the context of angular controllers services etc. since you can inject the services/factories wherever you need them and you can use directives to do DOM manipulations. The loading thing has been done to death so I'm not going to repeat it here but if you search for "angular loading spinner" I'm sure you'll find github repos with directives and or services to wrap any popular library. If you can't find one post back and I'll find some links. – shaunhusain Jan 07 '18 at 00:07
  • Also your script tags should all just be in your index.html. If you want to defer loading of some scripts you're going to need to do something fancy really or it will likely fall apart (the benefit of avoiding loading a few kb up front isn't worth it, compress some images and gzip all your server responses and you'll save much more) This might help too although no mention of jQuery still good conceptual overview https://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background – shaunhusain Jan 07 '18 at 00:09
  • @shaunhusain Thank you for your answer. Most of the wrappers I found talk about including small libraries, made by those who`s going to use them. But I couldn't find a definite answer what to do with bigger libraries. I uploaded the app here https://vardjaklap.github.io/testtwo/#!/view2 While loading first time it works, but after switching views the bar disappears. So what exactly should I do? – Alexander Peresta Jan 07 '18 at 10:24
  • @AlexanderPeresta same thing basically applies. Angular wants to be in control of the DOM since it uses an "html compiler" to find directives and run their code and update the view accordingly so that will generally run into problems if you are manipulating the DOM outside of the regular angular digest lifecycle. For things like bootstrap there is a good rewrite of most of the interactive components here https://angular-ui.github.io/bootstrap/ Angular is designed this way intentionally so controllers/services/factories/providers can be instantiated/tested without a view. – shaunhusain Jan 07 '18 at 10:26
  • @shaunhusain Thank you for replying so quickly! I will try to look everything step by step :) – Alexander Peresta Jan 07 '18 at 10:28

1 Answers1

0

http://plnkr.co/edit/IlOsCqn07sJLkQCMcUCk?p=preview

<div
        loading-bar
        class="ldBar label-center"
        style="width:50%;height:50%;margin:auto"
        data-value="35"
        data-preset="circle"
></div>

Directive to wrap the loading bar code using the JS function they provide for processing some element.

angular.module('loading-bar-angular', [])
  .directive('loadingBar', function(){
    return {

      link:function(scope,iElem,iAttr){
        new ldBar(iElem[0]);
        console.log('loading bar added')
      }
    }
  });

Without digging into it my guess is the plugin ordinarily just waits for the DOMContentLoaded and then looks for elements using querySelector or something similar. In the directive above I'm just using the element that the "loading-bar" attribute is added to and passing it to the loading-bar JS funciton.

https://loading.io/progress

Scroll to where it says JS API to see the ldBar function... I looked at the source to see that it also accepts a DOM element instead of a string to use as a selector.

shaunhusain
  • 19,630
  • 4
  • 38
  • 51