Насчет того, что у вас при нажатии "Заказать" добавляется в массив, но не пересчитывается сумма заказа:
У вас mainController объявлен на body, а потом объявлен в my-directive.
В начале mainController вы в скоупе создаете новую ссылку на массив orderList, totalPrice() вызывается на скоупе второго экземпляра mainController, в то время как добавление товара происходит в массив, объявленный в скоупе первого экземпляра mainController, а это два разных массива.
А убрать из директивы объявление контроллера вы не можете, потому что для директивы запрашиваете изолированный скоуп, в который само собой функция totalPrice() из скоупа, объявленного на body, не попадает.
Вам надо основательно разобраться сначала, как работаю скоупы в AngularJS, после чего узнать про controller as.
P.S. По архитектуре приложения ничего говорить не буду, не просили.
Вы столкнулись с проблемой из-за того, что захардкодили в контроллерах бизнес-логику. Это очевидный архитектурный недостаток. После его устранения у вас все начнет работать как нужно. Вам нужно вынести работу с корзиной в отдельный сервис:
module.service('Cart', function($rootScope, localStorageService){
var
currencies = {rub: 10800, usd: 1},
cartTotal = 0,
cartItems = localStorageService.get('zakaz') || [];
function updateCartTotal(){
var _total = 0;
angular.forEach(cartItems, function(item){
_total += item.price;
});
cartTotal = _total;
}
this.getTotal = function(currency){
var currency = currency || 'usd';
return cartTotal * (currencies[currency] || 1);
}
this.addItem = function(item){
cartItems.push(item);
updateCartTotal();
$rootScope.$broadcast('cart:updated', {cartSize: cartItems.length});
}
this.removeItem = function(item){
var idx = cartItems.indexOf(item);
if(idx > -1){
cartItems.splice(idx,1);
updateCartTotal();
$rootScope.$broadcast('cart:updated', {cartSize: cartItems.length});
}
}
this.isItemAddedAlready = function(item){
return cartItems.indexOf(item) > -1;
};
this.clear = function(){
cartItems.length = 0;
cartTotal = 0;
$rootScope.$broadcast('cart:updated', {cartSize: cartItems.length});
}
this.getItems = function(){
return cartItems;
}
});
Замечание: сейчас для поиска элемента в массиве ипользуется indexOf.
Он будет работать только когда корзина будет инициализироваться пустым массивом, потому что в этом случае при добавлении и удалении элементов будут использоваться одни и те же ссылки и равенство ссылок будет прокатывать. Для нормальной работы нужно либо писать костыль для поиска по ID, либо использовать underscore или lodash.
Теперь вы в контроллеры подключаете этот сервис через DI и везде, где нужно, используете его методы.
Для того, чтобы обновлять сумму и размер корзины делаете:
$scope.$on('cart:updated', function(event, info){
$scope.cartTotal = Cart.getTotal(currency);
$scope.cartSize = info.cartSize;
});
Мы бы могли сохранить ссылку на функцию сервиса у себя в контроллере и в шаблоне вызывать ее, типа {{getTotal(currency)}}, но так делать не стоит, потому что это лишний нагруженный watcher. Сейчас вы его, конечно, не почувствуете, но помнить о таких моментах надо всегда. Поэтому мы подписались на событие корзины и когда корзина изменяется, вытаскиваем нужную информацию.
Перепишите код с использованием сервиса, и увидите как он изменится в лучшую сторону. Ну а про удобство автоматизированного тестирования пока, думаю, смысла нет.