Angular.js - Apply filter using an interval

你说的曾经没有我的故事 提交于 2019-12-08 18:18:42

问题


I am using a custom angular.js filter for datetime objects:

function relativeTimeFilter()
{
    return function (dateObj) {
        return getRelativeDateTimeString(dateObj);
    };
}

function getRelativeDateTimeString(dt)
{
    if(!dt) return "undefined ago";

    var delta = dt.getSeconds();
    if (delta < 0) return "not yet";
    if (delta < 1 * 60) return delta == 1 ? "one second ago" : delta + " seconds ago";
    if (delta < 2 * 60) return "a minute ago";
    if (delta < 45 * 60) return Math.floor(delta/60) + " minutes ago";
    if (delta < 90 * 60) return "an hour ago";
    if (delta < 24 * (60*60)) return Math.floor(delta/60/60) + " hours ago";
    if (delta < 48 * (60*60)) return "yesterday";
    if (delta < 30 * (24 * (60*60))) return Math.floor(delta/60/60/24) + " days ago";
    if (delta < 12 * (30 * (24 * (60*60))))
    {
        var months = Math.floor(delta/60/60/24/30);
        return (months <= 1) ? "one month ago" : (months + " months ago");
    }
    else
    {
        var years = Math.floor(delta/60/60/24/365);
        return (years <= 1) ? "one year ago" : (years + " years ago");
    }
}

module.filter("relativetime", relativeTimeFilter);

At this point, it is not so important which filter I use (I think). The filter receives a Datetime object. The relative time declaration is only valid one second. Meaning one second ago must be updated after a second to 2 seconds ago and so on.

When I apply the filter, this only happens once. So how do I trigger the filter appliance in a regular interval?

I tried the following:

setInterval(function() {$scope.$apply()}, 1000) // placed in controller function

...with no success.

Any ideas?


回答1:


I don't think you are going to be able to achieve this with a filter. The reason $scope.$apply() doesn't work is because it is watching for changes on the data. Since the data didn't actually change, the filter never gets called again.

Instead, you need to adjust the data that is being viewed in your controller. Use $timeout instead of setInterval because it is built into the digestion lifecycle.

I'd consider using a directive to do this.

app.directive('relativeTime', function($timeout) {

  function update(scope, element) {
    element.text(getRelativeDateTimeString(scope.actualTime));
    $timeout(function() { update(scope, element); }, 1000);
  }

  return {
    scope: {
      actualTime: '=relativeTime'
    },
    link: function(scope, element) {
      update(scope, element);
    }
  };
});

So you can use the directive like this:

<div relative-time="theDate"></div>

Also, I found a flaw in your getRelativeDateTimeString function. You need to base your delta off of the current time. getSeconds just gives you the seconds of the given time:

var delta = parseInt(((new Date().getTime()) - dt.getTime()) / 1000);

Here is a working CodePen.




回答2:


Below is the working jsfiddle uses directive to update the time, I think you are looking for similar code..

http://jsfiddle.net/vishalvasani/xRg3j/

it uses

$timeout


来源:https://stackoverflow.com/questions/18570121/angular-js-apply-filter-using-an-interval

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!