2015-01-17 3 views
0

В моем приложении у меня есть директива магазина, у которой есть атрибут цены. Когда пользователь нажимает на эту директиву, общая стоимость (переменная, хранящаяся в родительском контроллере) обновляется по цене щелкнутого элемента.Торговая директива Сфера выпуска

Однако на данный момент я не могу передать атрибут цены в директиве магазина к родительскому контроллеру. Любая помощь, пожалуйста?

HTML:

<div ng-app="Shop" ng-controller="MainCtrl"> 
    <p>The total is {{ total }}.</p> 
    <shop-item price="100"></shop-item> 
</div> 

JavaScript:

var app = angular.module('Shop', []); 

app.controller('MainCtrl', ['$scope', 
    function($scope) { 
    $scope.total = 0; 
    } 
]); 

app.directive('shopItem', function() { 
    return { 
    restrict: 'E', 
    template: '<div class="shop-item">Shop Item</div>', 
    scope: { 
     price: '@' 
    }, 
    link: function(scope, element, attrs) { 
     element.on('click', function() { 
     // How can I update the parent scope's total by the attribute 'price' of this directive? 
     }); 
    } 
    }; 
}); 

ответ

1

Там может быть много способов подойти к этому. Но простая директива как ваша, вы могли бы также использовать привязку функции для регистрации события щелчка или даже использовать двустороннюю привязку.

связывание

<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

+0

Спасибо за ваш ответ! В любом случае, я могу достичь такого же поведения, не передавая общую сумму корзины в каждую директиву магазина, которую я определяю (используя total = «total», как вы это делали выше)? – srikarg

+1

@srikarg да я обновляю .. :) – PSL

+1

Смотрите мое обновление ... – PSL