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

Added support for one time binding using the '::' expression. #54

Merged
merged 1 commit into from
Jun 5, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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