jeudi 4 novembre 2021

AngularJS ng-repeat with track by renders very slow

When using AngularJS ng-repeat with track by in my web application, when the view is updated the old view is still displayed together with the new view during 1 second or so.

The app displays this panel of alarms (it is a home assistant app). Alarms can be enabled, disabled or removed using the icon buttons:

enter image description here

When the user click the icon button in the middle, the view is updated to this:

enter image description here

But when the view is updated, during half a second or so, it is displayed the old view and the new view together at the same time:

enter image description here

Is this a expected behaviout using ng-repeat with track by?. The code in my html view is:

...
<tr ng-repeat= "alarm in GetAlarmsController.alarms track by alarm.getId()" >
    <td class="text-right">
        <span ng-switch="alarm.isEnabled()">
            <button ng-switch-when="false" type="button" rel="tooltip" disabled class="btn btn-danger btn-icon btn-sm" >
                <i class="fa fa-power-off"></i>
            </button>
            <button ng-switch-when="true" type="button" rel="tooltip" disabled class="btn btn-success btn-icon btn-sm" >
                <i class="fa fa-power-off"></i>
            </button>
        </span>                   
    </td>
    <td class="text-right" ng-switch="alarm.isEnabled()">
        <button ng-switch-when="false"  type="button" rel="tooltip" class="btn btn-danger btn-icon btn-sm" ng-click="GetAlarmsController.enableAlarm(true, alarm.getId())">
            <i class="fa fa-toggle-off"></i>
        </button>
        <button ng-switch-when="true"  type="button" rel="tooltip" class="btn btn-success btn-icon btn-sm" ng-click="GetAlarmsController.enableAlarm(false, alarm.getId())">
            <i class="fa fa-toggle-on"></i>
        </button>
        <button type="button" rel="tooltip" class="btn btn-danger btn-icon btn-sm" ng-click="GetAlarmsController.deleteAlarm(alarm.getId())">
            <i class="fa fa-times"></i>
        </button>                          
    </td>
</tr>                
...

And, in the JS controller:

...
self.getAlarms = function(){
    AlarmAPIService.getAlarms()
    .then(function(alarms) { 
        self.alarms = alarms;   
    },function() {
        self.alarms = [];
    })
}
...
const ALARMS_REFRESH_TIME_MS = 5000 ;
var refreshAlarmsInterval = $interval(self.getAlarms, ALARMS_REFRESH_TIME_MS);
...
...
self.enableAlarm = function(enable, alarmId){
    enableString = (enable ? 'enabled' : 'disabled') ;
    AlarmAPIService.enableAlarm(enable, alarmId)
    .then(function() { 
        SweetAlertService.showSuccessAlert('Alarm ' + enableString + ' with success');
    },function() {
        SweetAlertService.showErrorAlert('Alarm could not be ' + enableString);
    })
}
...

Though self.alarm is assigned to a new array of alarms objects in controller, I have checked that the id of this alarms objects remains the same (only changed its state, specifically the enabled state for the alarm enabled)




Aucun commentaire:

Enregistrer un commentaire