celsomtrindade
celsomtrindade

Reputation: 4671

AngularJs update value in view when data factory change

I have a service factory I'm building to create a shopping cart system. Everything is working fine until now, excepet I can't update the cart items in the html when the service has a new item added/removed/updated quantity.

This is my factory:

function factCart () {
    var spCart = [];
        spCart['item'] = [];
        spCart['address'] = {
            //statics value based on cliente
        };

    var service = {
        getCart:        _getCart,
        addItem:        _addItem
    };
    return service;
    /* --- */
        function _getCart() {
            return spCart;
        };

        function _addItem(newItem) {
            spCart['item'].push(newItem);
        };
};

And this is how I add an item to the cart, with a directive:

function spAddItem(factCart) {
    return {
        restrict:'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                e.stopPropagation();
                var newItem = {
                    id: attrs.itemid,
                    name: itemitem,
                    value: itemvalue
                };
                factCart.addItem(newItem);
            });
        }
    }
}

And this is how I reference it to the dom (controller + html):

sp.cart = factCart.getCart();

<p>Shopping Cart:</p>
<ul>
    <li ng-repeat="items in sp.cart.item">Name: {{items.name}}</li>
</ul>

The item array is updating properly, I've checked with console logs, everything is working, except the view doesn't update when I add a new item, change it's quantity, etc..

I noticed it updates only if I change the view. But If I'm whitin the same view, nothing happens.

What may be happening?

Upvotes: 0

Views: 1510

Answers (2)

charlietfl
charlietfl

Reputation: 171679

The problem is that DOM events are not done within angular context so angular needs to be notified to run a digest to update view if those external events make scope changes

That's why angular has event directives like ng-click , ng-blur etc which internally will start digest

If you must use events outside of angular core to update scope you need to use one of the various methods like $apply()

  element.bind('click', function(e) {
            e.stopPropagation();
            var newItem = {
                id: attrs.itemid,
                name: itemitem,
                value: itemvalue
            };
            factCart.addItem(newItem);
            scope.$apply();// tell angular to run digest
        });

Upvotes: 1

aitnasser
aitnasser

Reputation: 1246

add to your ng-repeat track by $index ie:

<li ng-repeat="items in sp.cart.item  track by $index">Name: {{items.name}}</li>

Upvotes: 0

Related Questions