0

I am trying to create a simple loading directive, that I can use over and over, but I don't seem to get it working. I have the following code.

var river = angular.module('river', []);

river.directive('riverLoading', function() {
  return {
    restrict: 'E',
    template: '<div class="text-center" style="padding-bottom: 20px;" ng-show="loading">' +
    '<i class="fa fa-fw fa-refresh fa-spin" style="margin-right: 5px;"></i> {{ message }} {{ loading }}' +
    '</div>',
    scope: {
      acessor: '=',
      message: '@'
    },
    controller: function ($scope) {
      $scope.loading = true;
      
      $scope.finished = function() {
        $scope.loading = false;
      };
    }
  }
});

river.controller('ClientController', function($scope) {
  // This is in an $http.finished.
  // $scope.loadingClients.finished(); // This does not work (why?)
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="river" ng-controller="ClientController">

<river-loading acessor="loadingClients" message="Loading clients.."></river-loading>
  
</div>

How can I get this to work and what am I doing wrong? I see other examples that are doing the same thing and they work. But they usually don't have an isolated scope and just call $scope.finished();.

Thanks a lot for your time and help!

1 Answers1

0

It's very strange what you are doing, as you could just use the two-way binding. However, I think your problem is that you need your finished function to be:

$scope.acessor.finished = function() {
    $scope.loading = false;
};

i.e. you want to bind a finished function on the reference that you've passed in. However, it would be much simpler to just have your template in your directive to look like this:

template: '<div class="text-center" style="padding-bottom: 20px;" ng-show="loading.show">' +
'<i class="fa fa-fw fa-refresh fa-spin" style="margin-right: 5px;"></i> {{ message }} {{ loading }}' +
'</div>',

Remove your controller from the directive, and your ClientController becomes:

river.controller('ClientController', function($scope) {
  $scope.loading = {show: true}
  // This is in an $http.finished.
  // $scope.loadingClients.finished(); // This does not work (why?)
  $scope.loading.show = false
});

That way you can just use the 2-way data binding.

I would also read up on using a dot ('.') in your scopes as otherwise you'll end up with the Javascript object shadowing problem. See here.

Community
  • 1
  • 1
ajkavanagh
  • 116
  • 1
  • 3