强制重新编译已过滤的ng-attr而不更改$ scope

时间:2016-01-01 20:05:54

标签: javascript angularjs angularjs-directive

我正在编写一个聊天应用程序,其中我希望在消息上具有人类可读的相对时间戳。我正在使用一个过滤器,它接受JS时间戳和(使用Moment.js库)输出一个表示相对时间的字符串(例如"几秒钟之前")。以下是相关的代码摘录:

HTML:

<li ng-attr-title="{{timestamp | moment}}"></li>

JS:

angular.module("ChatApp").
filter("moment",function(){
    return function(jstimestamp){
        //using the Moment.js library to create a relative-time string
        return moment(parseInt(jstimestamp)).fromNow();
    }
});

即使ng-attr-title永远不会改变,我如何强制AngularJS定期重新计算$scope.timestamp,以便在几秒钟之前&#34;&#34;将在一分钟前更新为&#34;&#34;等等?目前它仅在重新加载页面时更新。

2 个答案:

答案 0 :(得分:2)

你可以尝试使你的过滤器有状态,这样即使输入值没有改变,它也会在每个摘要上进行评估。

angular.module("ChatApp").
filter("moment", function() {

  function innerFilter(jstimestamp) {
    //using the Moment.js library to create a relative-time string
    return moment(parseInt(jstimestamp)).fromNow();
  }
  innerFilter.$stateful = true;

  return innerFilter;
});

您可以在控制器中添加间隔,使其无需用户输入即可使用。

var intervalPromise = $interval(function() {}, 1000);

$scope.$on('$destroy', function() {
   $interval.cancel(intervalPromise);
});

不需要在间隔内调用apply,因为$ interval的每个tick都会触发一个摘要周期。

您可以看到一个有效的例子here

您可以在文档页面here中找到有关有状态过滤器的更多信息。

答案 1 :(得分:1)

这似乎是个坏主意,但它可以通过手动触发$apply周期来实现。警惕性能影响,因为它将在所有绑定上运行。这将每秒刷新你的绑定,你可以根据你的需要调整它:

angular.module('app', [])
.run(['$interval', '$rootScope', function ($interval, $rootScope) {
      $interval(function () {
        $rootScope.$apply();
      }, 1000, 0, false);
    }]);