Там может быть много способов подойти к этому. Но простая директива как ваша, вы могли бы также использовать привязку функции для регистрации события щелчка или даже использовать двустороннюю привязку.
связывание
<div ng-app="Shop" ng-controller="MainCtrl">
<shop-item price="100" total="total"></shop-item>
</div>
В директиве 2-полосная не связывают обработчик событий вручную вместо того, чтобы использовать угловые события, например, ng-click
app.directive('shopItem', function() {
return {
restrict: 'E',
/*register an ng-click*/
template: '<div class="shop-item" ng-click="addItem()">Shop Item</div>',
scope: {
price: '@',
total: '=' //<-- 2 way binding
},
link: function(scope, element, attrs) {
scope.addItem = function(){
//increment the price
scope.total = (scope.total || 0) + +scope.price;
}
}
};
});
plnkr
Функция привязка
Вы также можете использовать подход привязки к функциям, чтобы не обрабатывать цену, вместо этого вы просто уведомляете о событии addCart ценой, которая в вашем случае кажется более желательной, учитывая разделение проблем. Так что общий расчет производится только контроллером, который определяет цену, а не корзину. Но это, вероятно, этот пример у вас есть слишком просто, чтобы найти разницу, но если вы должны были сделать это таким образом тогда:
<shop-item price="100" total="total" on-add-cart="addToCart(price)"> </shop-item>
В контроллере:
$scope.addToCart = function(price){
$scope.total += price;
}
В директиве (как пример я добавить скидку в размере 5%):
app.directive('shopItem', function() {
return {
restrict: 'E',
/*register an ng-click*/
template: '<div class="shop-item" ng-click="onAddCart({price: (+price)*.95})">Shop Item</div>',
scope: {
price: '@',
onAddCart: '&' //<-- 2 way binding
},
link: function(scope, element, attrs) {
scope.addItem = function(){
//increment the price
scope.total = (scope.total || 0) + +scope.price;
}
}
};
});
Plnkr
Event Bus
Другой способ - использовать угловую шину событий. Посмотрите на различные варианты, такие как $emit
/$broadcast
с $on
. Возможно, вам придется выбирать между $ emit/$ broadcast на основе иерархии элементов DOM.
Это будет выглядеть так:
<shop-item price="100" total="total"> </shop-item>
В директиве:
return {
restrict: 'E',
/*register an ng-click*/
template: '<div class="shop-item" ng-click="onAddCart()">Shop Item</div>',
scope: {
price: '@'
},
link: function(scope, element, attrs) {
scope.onAddCart = function(){
scope.$emit("ITEM_ADDED", +scope.price); //emit an event with price
}
}
};
В контроллере:
$scope.$on('ITEM_ADDED', function(e, price){
$scope.total += price;
});
Plnkr
Спасибо за ваш ответ! В любом случае, я могу достичь такого же поведения, не передавая общую сумму корзины в каждую директиву магазина, которую я определяю (используя total = «total», как вы это делали выше)? – srikarg
@srikarg да я обновляю .. :) – PSL
Смотрите мое обновление ... – PSL