1

My Angular application needs to resolve data before the controller is loaded. I am using the answer provided here by tasseKATT:

Apply loading spinner during ui-router resolve

Though I am curious as to why I can use "template" but not "templateUrl."

Works:

app.directive('resolveLoader', function($rootScope, $timeout) {
  return {
    restrict: 'E',
    replace: true,
    template: '<div class="alert alert-success ng-hide"><strong>Welcome!</strong> Content is loading, please hold.</div>',
    link: function(scope, element) {...

Does not work:

app.directive('resolveLoader', function($rootScope, $timeout) {
      return {
        restrict: 'E',
        replace: true,
        templateUrl: 'loadingView.html',
        link: function(scope, element) {...

Please see the modified Plunker below (which does not work properly):

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

Community
  • 1
  • 1
cjones26
  • 3,459
  • 1
  • 34
  • 51
  • @slashhp Can you elaborate what is not working and how ur controlling ng-hide in loadingView.html file ..I removed it then able to see the template – swapnesh Oct 05 '15 at 15:03
  • why are you using `ng-hide` as class and not using it as attribute directive with a value? That is not how you normally use it – charlietfl Oct 05 '15 at 15:12
  • swapnesh & charlietfl, this was not originally my code, but rather the solution posted by tasseKATT--I was simply curious about why exactly his solution worked with "template" instead of "templateUrl." After reviewing the comment on the original answer pointed out by Floyd Pink, it appears this is a timing issue with the link function. Thanks for your input, though! – cjones26 Oct 05 '15 at 16:19
  • 1
    Shouldn't templateUrl: in the first resolveLoader directive be template: instead? – zszep Oct 05 '15 at 17:15
  • @zszep, you're right--I've fixed it. Thank you! – cjones26 Oct 05 '15 at 17:20

2 Answers2

1

As mentioned in the comment on the original answer, it is a timing issue and you would not need the $timeout when templateUrl is used.

So this:

link: function(scope, element) {

  $rootScope.$on('$routeChangeStart', function(event, currentRoute, previousRoute) {
    if (previousRoute) return;

    $timeout(function() {
      element.removeClass('ng-hide');
    });
  });

  $rootScope.$on('$routeChangeSuccess', function() {
    element.addClass('ng-hide');
  });
}

will change to:

link: function(scope, element) {

  element.removeClass('ng-hide');

  var unregister = $rootScope.$on('$routeChangeSuccess', function() {
    element.addClass('ng-hide');
    unregister();
  });
}

Here is the plunk with the fixed solution for using templateUrl (from the original answer's comment): http://plnkr.co/edit/31qu9xcZCCEzSfHn5YyN?p=preview

Hari Pachuveetil
  • 10,294
  • 3
  • 45
  • 68
  • I completely missed that comment but now I understand that it is in fact a timing issue. Thank you for pointing this out, as your solution has the code now working properly!! – cjones26 Oct 05 '15 at 16:17
1

As I stated in my comment, you have to replace templateUrl with template in the first directive and then it works like this plunker:

    app.directive('resolveLoader', function($rootScope, $timeout) {
      return {
        restrict: 'E',
        replace: true,
        // wrong
        //templateUrl: '<div class="alert alert-success ng-hide">
        // should be
        template: '<div class="alert alert-success ng-hide"><strong>Welcome!</strong> Content is loading, please hold.</div>',
        link: function(scope, element) {...

And then there is no timing issue, at least in my chrome browser.

zszep
  • 4,450
  • 4
  • 38
  • 58