Home How to use directive multiple times
Reply: 1

How to use directive multiple times

Paul
1#
Paul Published in 2017-11-14 16:47:56Z

Basically I have copied this code from another source which is a countdown timer.

Directive

app.directive('countdown', [
    'Util', '$interval', function (Util, $interval) {
        return {
            restrict: 'E',
            scope: {
                date: '@'
            },
            templateUrl: 'countdown_timer.html',
            link: function (scope, element) {
                var future = new Date(scope.date);

                var stop;

                stop = $interval(function () {
                    var diff;
                    diff = Math.floor((future.getTime() - new Date().getTime()) / 1000);

                    if (parseInt(diff) <= 0) {
                        stopTimer();
                        scope.days = 0;
                        scope.hours = 0;
                        scope.minutes = 0;
                        scope.seconds = 0;
                    } else {
                        var d = Util.dhms(diff);
                        scope.days = d[0];
                        scope.hours = d[1];
                        scope.minutes = d[2];
                        scope.seconds = d[3];
                    }
                }, 1000);

                stopTimer = function () {
                    console.log("Should Stop");
                    $interval.cancel(stop);
                };
            }
        };
    }
]).factory('Util', [
    function () {
        return {
            dhms: function (t) {
                var days, hours, minutes, seconds;
                days = Math.floor(t / 86400);
                t -= days * 86400;
                hours = Math.floor(t / 3600) % 24;
                t -= hours * 3600;
                minutes = Math.floor(t / 60) % 60;
                t -= minutes * 60;
                seconds = t % 60;
                return [days, hours, minutes, seconds];
            }
        };
    }
]);

HTML

<div class="col-xs-12" ng-repeat="event in events">
    <countdown date="{{ event.event_date }}"></countdown>
</div>

TEMPLATE

<div class='time_division_container'>
    <div class='digits_container'>{{ days }}</div>
    <div class='label_container'>DAYS</div>
</div>
<div class='time_division_container'>
    <div class='digits_container'>{{ hours }}</div>
    <div class='label_container'>HOURS</div>
</div>
<div class='time_division_container'>
    <div class='digits_container'>{{ minutes }}</div>
    <div class='label_container'>MINUTES</div>
</div>
<div class='time_division_container'>
    <div class='digits_container'>{{ seconds }}</div>
    <div class='label_container'>SECONDS</div>
</div>

This works fine at first if the countdown is only 1. But when I add multiple event_date in the event object the

$interval.cancel(stop);

seems not working.

For example if I have these event dates

var events = {
    {"event_date" : "2017-11-30 12:00:00"},
    {"event_date" : "2017-11-01 09:00:00"}
};

The first date is working fine but the second date which has already passed is not stopping its countdown. If you look at the console log it still displays "Should Stop" multiple times. It should only display once since I made and if statement that calls the "stopTimer" function when the difference of the current time and the event date is 0 or negative.

Please help. Thanks a lot.

james00794
2#
james00794 Reply to 2017-11-14 19:16:43Z

You have a scoping problem. stopTimer is being defined as a global variable, and each time the directive instantiates it overwrites the previous definition. So when you call stopTimer from the first directive, it calls the stopTimer defined in the second directive, who's stop variable is pointing to something else. Also, probably a typo in your question, but events should be an array for ng-repeat to work.

If you change:

  stopTimer = function () {
    console.log("Should Stop");
    $interval.cancel(stop);
  };

to

  var stopTimer = function () {
    console.log("Should Stop");
    $interval.cancel(stop);
  };

it works correctly, as stopTimer is now scoped. See the attached plunkr: https://plnkr.co/edit/41DlPAP07iBtmAq3kKbR

Aside, it's useful to enable strict mode to avoid scoping problems like this. See What does "use strict" do in JavaScript, and what is the reasoning behind it?. If strict mode were enabled, you would have seen an error in your console.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.343147 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO