Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

Commit

Permalink
Merge pull request #54 from ephigabay/issue_48
Browse files Browse the repository at this point in the history
Added support for one time binding using the '::' expression.
  • Loading branch information
urish committed Jun 5, 2014
2 parents f53e86f + 7139716 commit b54c341
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 16 deletions.
37 changes: 23 additions & 14 deletions angular-moment.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@
var currentFormat = angularMomentConfig.format;
var withoutSuffix = amTimeAgoConfig.withoutSuffix;
var preprocess = angularMomentConfig.preprocess;
var modelName = attr.amTimeAgo.replace(/^::/, '');
var isBindOnce = (attr.amTimeAgo.indexOf('::') === 0);
var unwatchChanges;

function cancelTimer() {
if (activeTimeout) {
Expand All @@ -117,19 +120,21 @@

function updateTime(momentInstance) {
element.text(momentInstance.fromNow(withoutSuffix));
var howOld = moment().diff(momentInstance, 'minute');
var secondsUntilUpdate = 3600;
if (howOld < 1) {
secondsUntilUpdate = 1;
} else if (howOld < 60) {
secondsUntilUpdate = 30;
} else if (howOld < 180) {
secondsUntilUpdate = 300;
}

activeTimeout = $window.setTimeout(function () {
updateTime(momentInstance);
}, secondsUntilUpdate * 1000);
if(!isBindOnce) {
var howOld = moment().diff(momentInstance, 'minute');
var secondsUntilUpdate = 3600;
if (howOld < 1) {
secondsUntilUpdate = 1;
} else if (howOld < 60) {
secondsUntilUpdate = 30;
} else if (howOld < 180) {
secondsUntilUpdate = 300;
}

activeTimeout = $window.setTimeout(function () {
updateTime(momentInstance);
}, secondsUntilUpdate * 1000);
}
}

function updateMoment() {
Expand All @@ -139,7 +144,7 @@
}
}

scope.$watch(attr.amTimeAgo, function (value) {
unwatchChanges = scope.$watch(modelName, function (value) {
if ((typeof value === 'undefined') || (value === null) || (value === '')) {
cancelTimer();
if (currentValue) {
Expand All @@ -151,6 +156,10 @@

currentValue = value;
updateMoment();

if(value !== undefined && isBindOnce) {
unwatchChanges();
}
});

if (angular.isDefined(attr.amWithoutSuffix)) {
Expand Down
2 changes: 1 addition & 1 deletion angular-moment.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion angular-moment.min.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 81 additions & 0 deletions tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,87 @@ describe('module angularMoment', function () {
}, 50);
});

it('should change the text of the element to "a few seconds ago" when given unix timestamp with one time binding', function () {
$rootScope.testDate = new Date().getTime() / 1000;
var element = angular.element('<span am-time-ago="::testDate" am-preprocess="unix"></span>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('a few seconds ago');
});

it('should change the text of the element to "a few seconds ago" when given current time with one time binding', function () {
$rootScope.testDate = new Date();
var element = angular.element('<span am-time-ago="::testDate"></span>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('a few seconds ago');
});

it('should change the text of the div to "3 minutes ago" when given a date 3 minutes ago with one time binding', function () {
$rootScope.testDate = new Date(new Date().getTime() - 3 * 60 * 1000);
var element = angular.element('<div am-time-ago="::testDate"></div>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('3 minutes ago');
});

it('should change the text of the div to "2 hours ago" when given a date 2 hours ago with one time binding', function () {
$rootScope.testDate = new Date(new Date().getTime() - 2 * 60 * 60 * 1000);
var element = angular.element('<div am-time-ago="::testDate"></div>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('2 hours ago');
});

it('should change the text of the div to "one year ago" when given a date one year ago with one time binding', function () {
var today = new Date();
$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());
var element = angular.element('<div am-time-ago="::testDate"></div>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('a year ago');
});

it('should parse correctly numeric dates as milliseconds since the epoch with one time binding', function () {
$rootScope.testDate = new Date().getTime();
var element = angular.element('<div am-time-ago="::testDate"></div>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('a few seconds ago');
});

it('should not update the value if date changes on scope when using one time binding', function () {
var today = new Date();
$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()).getTime();
var element = angular.element('<div am-time-ago="::testDate"></div>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('a year ago');
$rootScope.testDate = new Date();
$rootScope.$digest();
expect(element.text()).toBe('a year ago');
});

it('should not update the span text as time passes when using one time binding', function (done) {
$rootScope.testDate = new Date(new Date().getTime() - 44000);
var element = angular.element('<div am-time-ago="::testDate"></div>');
element = $compile(element)($rootScope);
$rootScope.$digest();
expect(element.text()).toBe('a few seconds ago');

var waitsInterval = setInterval(function () {
// Wait until $rootScope.date is more than 45 seconds old
if (new Date().getTime() - $rootScope.testDate.getTime() < 45000) {
return;
}

clearInterval(waitsInterval);
$rootScope.$digest();
expect(element.text()).toBe('a few seconds ago');
done();
}, 50);
});

it('should handle undefined data', function () {
$rootScope.testDate = null;
var element = angular.element('<div am-time-ago="testDate"></div>');
Expand Down

0 comments on commit b54c341

Please sign in to comment.