有一个指令听一个函数

时间:2013-01-31 10:05:48

标签: javascript angularjs

我有以下代码:

HTML

<div id="header">
    <h1>The JSON Store</h1>
    <div class="cart-info" ng-controller="CartController" quantity="basketContents">
        My Cart (<span class="cart-items">{{basketCount()}}</span> items)
    </div>
</div>
<div id="main" ng-view></div>

的JavaScript

app.controller(
    'CartController',
   function ($scope, basketService) {
       $scope.basketCount = basketService.getCount;
       $scope.basketContents = basketService.items;
   }
);




app.factory('basketService', function () {
    return {
        getCount: function () {
            var basket = JSON.parse((localStorage.getItem('shoppingBasket') || '{ "items": [] }'));
            var count = 0;
            basket.items.forEach(function (element) {
                count += element.quantity;
            });

            return count;
        },

        get items() {
            var basket = JSON.parse((localStorage.getItem('shoppingBasket') || '{ "items": [] }'));
            var quantities = basket.items.map(function (x) { return x.quantity; });
            if (quantities.length > 0) {
                var total = quantities.reduce(function (previousValue, currentValue) { return previousValue + currentValue; });
                return total;
            } else {
                return 0;
            }
        },

        addItem: function (item) {
            var basket = JSON.parse((localStorage.getItem('shoppingBasket') || '{ "items": [] }'));

            var itemStoredAlready = basket.items.filter(function (x) { return x.id === item.id; }).length === 1;

            if (itemStoredAlready) {
                var basketItem = basket.items.filter(function (x) { return x.id === item.id; })[0];
                basketItem.quantity += parseInt(item.quantity, 10);
            } else {

                var basketItem = {};
                basketItem.id = item.id;
                basketItem.title = item.title;
                basketItem.quantity = parseInt(item.quantity, 10);

                basket.items.push(basketItem);
            }

            localStorage.setItem('shoppingBasket', JSON.stringify(basket));
        }
    };
});




app.directive('quantity', function () {
    var linker = function (scope, element, attrs, basketService) {

        scope.$watch(attrs.quantity, function (value, oldValue) {
            if (value > oldValue) {
                alert("added");
            }

        }, true);
    };

    return {
        restrict: 'A',
        link: linker
    };
});

然后我有其他控制器来处理“主”div的模板。在其中一个控制器中,它调用basketService.addItem并且视图由basketCount()更新(我不完全理解这是如何发生的,有些事情正在触发我假设)

addItem被调用时,我想做一些jQuery动画或fadeIn,我知道我必须使用指令,但我无法理解我如何获得指令来观察addItem函数然后做一些jQuery的东西。正如您所看到的,我试图在basketService中设置CartController Scope和自定义HTML元素中的属性,但是当添加某些内容时,HTML元素没有得到更新,并且指令功能是没有被召唤。

感谢您的帮助

这是一个Plunker - http://plnkr.co/edit/gis0114bTRRJLHCdYnMG?p=preview

2 个答案:

答案 0 :(得分:0)

动画应该在指令内(就像你说的那样)。

控制器应该将指令绑定到属性,该属性在服务中更改计数时会更改。在指令中使用隔离范围时,可以实现此目的。

以下是一个示例,您可以使用jQuery逻辑更改css():http://plnkr.co/edit/Mi5QzViUgl5mS21EAKh6?p=preview

希望它有所帮助,

答案 1 :(得分:0)

  

我无法理解我是如何获得指令来观察addItem函数然后做一些jQuery的东西

通常,您需要$观看范围属性,而不是函数。这是一种方法,我认为简化了事情:

  • 在basketService上创建一个计数器原语。添加项目时增加此属性。
  • 在CartController上创建一个引用basketService的篮子属性
  • 数量指令中的
  • $ watch('basket.counter')
  • 因为数量指令没有创建新的隔离范围,所以它不需要值 - 即只需<div class="..." ng-controller="..." quantity>就足够了

Plnkr

还有其他方法,比如@ShaiRez建议 - 使用隔离范围。这更复杂,因为您需要了解隔离范围如何工作,并且您需要使用属性将信息传递到隔离范围,但它确实使您的指令更具可重用性。

其他一些观察结果:

  • 而不是getCount()函数(每个摘要周期重新评估),而不是itemCount属性。该属性将作为“添加”和“删除”操作的一部分进行更新。
  • 你的plnkr非常大。对于将来的问题,最好创建一个最小的例子。 (你会有更多人看到它,你会得到更快的回复)。