how to defer a method execution in a directive in

2019-08-05 03:22发布

I'm writing a directive which recives a function as a parameter, the directive executes and run whatever is contained into the function.

the use case is:

  • the directive contains a link
  • when the user click the link the method passed as a parameter (from the controller) is executed
  • when the user hit the click button a spinner will show
  • the spinner will hide when the execution of the method is finished

my question is how can I defer the execution and bind it to a promise, to hide the spinner after the method execution.

for illustration purposes I have used $timeout that counts from 3 to 1, please take a look to the code I've done so far:

app.directive('toogleTextLink', function($compile,$q) {
    return {
        restrict: 'AE',
        scope: { callback: "&targetMethod" },
        template: '<div><a style="cursor: pointer" ><b>{{text}}</b></a>show value= {{show}}  <br/><div ng-class="{previewLoader: show}"></div></div>',
        link: function (scope, element, attr) {
            scope.value = attr.value;
            scope.show = false;
            scope.$watch('value', function () {
                    if (scope.value) {
                        scope.text = "yes";
                    } else {
                        scope.text = "no";
                    }
            });
            element.bind('click', function () {
                scope.show = true;
                scope.value = !scope.value;
                scope.$digest();
                if (scope.callback) {
                    var deferred = $q.defer(scope.callback());
                    deferred.promise.then(function () {
                        scope.show = false;
                        console.log("then called");
                    });

                }

            });
        }
    };
});

  app.controller('myCtrl', function($scope,$timeout,$q) {
  $scope.IsFacebookConnected = false;
  $scope.countDown = 3;
  $scope.authSocial = function(value, socialNetwork) {
        switch (socialNetwork) {
            case "facebook":
                $scope.IsFacebookConnected = !value;
        }

         runCounter = function() {
             $scope.countDown -= 1;            
            if ( $scope.countDown > 0)        
                $timeout(runCounter, 1000); 
                console.log("timer");
        };
        runCounter();
    };

});

this is the plunker as well.

1条回答
等我变得足够好
2楼-- · 2019-08-05 04:11

Andy Joslin wrote a "promise tracker" which does exactly what you need. It even has some sugar for $http integration. Basically you add "promises" to it, and it tells you the execution state. You can then bind that execution state to ng-show on something like a loading spinner animation. https://github.com/ajoslin/angular-promise-tracker and here's a demo: http://plnkr.co/edit/3uAe0NdXLz1lCYlhpaMp?p=preview

Your code will look something like:

$scope.tracker = promiseTracker("socialtracker");
$scope.tracker.addPromise(somePromise);

And in your view:

<div ng-show="tracker.active()">Loading...</div>
查看更多
登录 后发表回答