You can create new plain list in your model to iterate over and use it instead of using nested loops. If data is to be changed then you can watch changes of dependent properties and reassemble plain list for each change. Something like this:
JavaScript
angular.module('app',[]).
controller('appController', function($scope) {
var i, j;
$scope.week = 1;
$scope.days = [{
day: 1,
month: 2,
year: 2014
}, {
day: 2,
month: 2,
year: 2014
}, {
day: 3,
month: 2,
year: 2014
}];
$scope.shifts = ['Shift1', 'Shift2', 'Shift3'];
// Create new plain list each time shifts is changed
$scope.$watchCollection('shifts', function() {
$scope.daysShifts = [];
for(i=0; i<$scope.days.length; i++) {
for(j=0; j<$scope.shifts.length; j++) {
$scope.daysShifts.push({
name: $scope.shifts[j]
});
}
}
});
$scope.addShift = function() {
$scope.shifts.push('Shift'+($scope.shifts.length+1));
}
});
HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js@*" data-semver="1.2.11" src="http://code.angularjs.org/1.2.11/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="appController">
<div>
<table>
<caption>Week: {{week}}</caption>
<thead>
<tr>
<th ng-repeat="day in days" colspan="{{shifts.length}}">
<span>{{day.day}}/{{day.month}}/{{day.year}}</span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="dayShift in daysShifts">
<span>{{dayShift.name}}</span>
</td>
</tr>
</tbody>
</table>
</div>
<button ng-click="addShift()">Add Shift</button>
</body>
</html>
Plunker: http://plnkr.co/edit/zZYrurhp3HQA9Jp9QHDo?p=preview