Prevent Angular from binding every second

时间:2015-10-02 17:17:53

标签: javascript angularjs

I am displaying users in a table with ng-repeat. One of the columns, "Status" is computed by a function and can return a value 'Active', 'Idle' or 'Locked'. The function uses the current date time to calculate this.

If LastAccess is within the last 5 minutes, the 'Active' status is displayed.

Here is what the table looks like:

enter image description here

以下是HTML标记:

<tr ng-repeat="user in UserTable.Rows" ng-click="openUser(user.UserID)">
  <td>{{user.FirstName}} {{user.LastName}}</td>
  <td>{{user.Email}}</td>
  <td>{{user.OfficeName}}</td>
  <td>{{user.DeptName}}</td>
  <td>{{user.RoleName}}</td>
  <td><span class="label label-{{getStatus(user)=='Idle'?'default':(getStatus(user)=='Locked'?'danger':'success')}}">{{getStatus(user)}}</span>    </td>
  <td>{{user.LastAccess|timeAgo}}</td>
</tr>

以下是getStatus的功能:

$scope.getStatus = function (usr) {
  if (usr.Locked) return 'Locked';
  if (!usr.LastAccess) return 'Idle';
  var diff = (new Date().getTime() - new Date(usr.LastAccess).getTime()) / 1000;
  console.log(diff);
  if (diff < 300) return 'Active'; else return 'Idle';
}

问题是每个用户每秒调用一次该函数(根据console.log函数)。我理解为什么它被调用三次(因为它在HTML中使用了三次)。但是,我可以阻止每一秒更新吗?每分钟调用一次这个函数就足够了。我该怎么做?

有没有更好的方法可以在不创建过滤器的情况下执行此操作?

1 个答案:

答案 0 :(得分:2)

不要在元素中执行该功能。而是为显示Status的元素编写指令。然后在指令内使用$ interval来调用updater函数。

将元素中的用户索引作为属性包含在内。像这样:

<span statusupdater useridx={{UserTable.Rows.indexOf(user)}}></span>

现在指令是这样的:

myApp.directive('statusupdater', function($interval) {
        return {            
            link: function (scope, element) {

                function update(scope, ele) {

                    var userIdx = ele.attr("useridx");
                    var user = scope.UserTable.Rows[userIdx];

                    //Now process your user and change the style(or class) and html of the 
                    //span element accordingly                    
                };            

                $interval(function(){
                    update(scope, element);
                }, 18000);

        }
 }

现在更新功能将每隔3分钟执行一次。它根据用户状态更改每个跨度的类和html。

请注意,此方法会创建闭包,如果您在单个页面中有大型列表,则可能不适用。在这种情况下,您需要以不同的方式引用范围和元素。

另请注意,如果使用分页来显示用户列表,则应跟踪$ interval调用的返回承诺并相应地取消它们。

更新 如果你有自动更新html(如问题中所说的每一秒?),还要确保你只添加一些条件来执行指令一次。或者只是在你的控制范围内禁用它。