JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://momentjs.com/downloads/moment.min.js"></script>
<div ng-controller="TasksCtrl">
<button ng-click="refresh()">Refresh Tasks</button> Click this to feel the delay, then change the HTML on the left to see the no-delay version that uses "track by"
<button ng-click="add()">add</button>
<button ng-click="update()">update</button>
<button ng-click="updateId()">updateId</button>
<button ng-click="remove()">remove</button>
<button ng-click="updateNested()">updateNested</button>
<button ng-click="updateNestedArray()">updateNestedArray</button>
<ul class="tasks">
<!-- Try commenting the line below and uncommenting the other -->
<li ng-repeat="task in tasks" task="task" class="task">123</li>
<!--<li ng-repeat="task in tasks track by task.id" task="task" class="task"></li>-->
</ul>
</div>
CSS
.tasks {
max-height: 19em;
overflow-y: scroll;
border: 3px solid #ccc;
list-style: none;
padding: 0;
}
.tasks .task {
padding: 0.5em;
border: 1px solid #007aff;
}
.tasks .task .time {
color: #8f8f8f;
font-size: 0.7em;
}
JavaScript
angular.module('myApp', [])
.controller('TasksCtrl', function($scope) {
var date = new Date().toISOString();
$scope.tasks = [];
for (var i = 1; i < 301; i++) {
$scope.tasks.push({
id: i,
title: 'Task ' + i,
date: date,
nested: {name: 'N'+i,value: i},
nestedArray: [{name: 'first'}]
});
}
$scope.add = function() {
id = $scope.tasks[0].id-1;
$scope.tasks.unshift({
id: id,
title: 'Task 0',
date: 'a',
nested: {name: 'N'+id,value: id},
nestedArray: [{name: 'first'}]
});
}
$scope.remove = function() {
$scope.tasks.shift();
}
$scope.update = function() {
$scope.tasks[0].title = $scope.tasks[0].title + 'a';
}
$scope.updateId = function() {
$scope.tasks[0].id = $scope.tasks[0].id - 1;
}
$scope.updateNested = function() {
$scope.tasks[0].nested.name = $scope.tasks[0].nested.name + 'a';
}
$scope.updateNestedArray = function() {
$scope.tasks[0].nestedArray[0].name = $scope.tasks[0].nestedArray[0].name + 'a';
}
$scope.refresh = function() {
console.log("refreshing")
$scope.tasks = angular.copy($scope.tasks);
};
})
.directive('task', function() {
return {
scope: {
task: '='
},
template: '{{ task.id }} {{ task.title }} <span class="time">({{ prettyTaskDate }})</span>{{ task.nested.name}} {{ task.nested.value}} {{ task.nestedArray[0].name }}',
link: function(scope) {
console.log('rendering', scope.task.id);
scope.$watch('task.date', function() {
scope.prettyTaskDate = scope.task.date;
});
}
};
});