刷新过滤器(在项目上)而不更改ng-repeat模型

时间:2016-03-02 09:29:56

标签: javascript angularjs

我有一个过滤器,可以将日期格式化为'很久以前'格式(momentjs)。我希望过滤值能够重现'随着时间的推移,不改变模型。

例如:

  • 当前日期显示"几秒钟前"
  • 过了一段时间我想 将价值改为"几分钟前"
  • 等...

https://jsfiddle.net/u66aaz3u/1/

的功能示例



var app = angular.module('test', []);
app.filter('fromNow', function(){
	return function(value){
  	return moment(value).fromNow();
  }
});

app.controller('TestCtrl', function($scope, $interval){
	$scope.list = [
  	{
    	text: 'foo',
      date: moment()
    }
  ];
  
  var counter = 0
  $interval(function(){
  	counter++;
  	$scope.list[0].date = moment().subtract(counter, 'minutes');
  }, 1000)
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="TestCtrl">
  <div ng-repeat="item in list">
    {{item.text}} - {{item.date | fromNow}}
  </div>
</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

一种方式是有状态过滤器,如here所述。新过滤器定义的不同之处仅在于它包含$stateful标志:

app.filter('fromNow', function(){
    function fromNow(value){
    return moment(value).fromNow();
  }

  fromNow.$stateful = true;

  return fromNow;
});

并且您需要定期运行摘要,因此空间隔函数将执行:

$interval(function() {
    // NOTHING
}, 2000);

查看here

但是,如上面链接的过滤器参考页中所述:

  

强烈建议不要编写有状态的过滤器,因为Angular会优先执行这些过滤器,这通常会导致性能问题。只需将隐藏状态作为模型公开并将其转换为过滤器的参数,就可以将许多有状态过滤器转换为无状态过滤器。

如果您可以实际丰富模型,甚至使用替代视图模型,那么会更有效,以免污染您的主模型。 E.g:

// in the controller:
  // watch so that you can respond to changes in the list; if not necessary, just omit this line (and)
  $scope.$watchCollection('list', calculateFromNowList);

  function calculateFromNowList(list) {
    $scope.fromNowList = list.map(function(x) {
        return x.date.fromNow();
    });
  }

  $interval(function() {
    calculateFromNowList($scope.list)
  }, 1000)

您不再需要过滤器,只需将模板更改为:

<div ng-repeat="item in list">
    {{item.text}} - {{fromNowList[$index]}}
</div>

上面的代码定期计算&#34;从现在开始&#34;字符串到一个单独的模型并显示。相关小提琴here

我担心的是,此代码每秒触发摘要周期,仅用于非常具体的更改。如果出现性能问题,使用几个指令和浏览器setInterval直接更新DOM可能更有效,例如:如在this fiddle中那样。此解决方案 DIRTY ,但在性能出现问题时,此处作为最后的手段包含在内。