购物指令范围问题

时间:2015-01-17 04:10:36

标签: javascript angularjs

在我的应用程序中,我有一个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?
      });
    }
  };
});

1 个答案:

答案 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