在我的应用程序中,我有一个shop item指令,它有一个price属性。当用户单击该指令时,总成本(存储在父控制器中的变量)将根据所单击项目的价格进行更新。
但是,截至目前,我无法将shop item指令中的price属性传输到父控制器。有什么帮助吗?
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?
});
}
};
});
答案 0 :(得分:1)
有很多方法可以解决这个问题。但是你可以使用一个简单的指令,使用函数绑定来注册click事件,甚至使用双向绑定。
双向绑定
<div ng-app="Shop" ng-controller="MainCtrl">
<shop-item price="100" total="total"></shop-item>
</div>
在指令中,不要手动绑定事件处理程序,而是使用角度事件,例如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 强>
活动巴士
另一种方法是使用角度事件总线。查看$emit
/ $broadcast
和$on
等各种选项。您可能必须根据DOM元素的层次结构在$ emit / $ broadcast之间进行选择。
看起来像:
<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 强>