简体   繁体   中英

How to make the number of items in my cart update in real time in my Angular app?

I'm currently in the middle of the Iron Yard program and we moved onto Angular this week. We did Backbone last week and so far, I think Angular is leaps and bounds ahead of it.

I've only been working with frameworks for those two weeks though, so the whole MVC concept is still a bit fuzzy to me. Going from being able to freely manipulate elements with jQuery to having to go through a bunch of services and controllers is a big change for me.

This is what my project looks like, it's a very basic store built on the Etsy API:

http://claytonkinder.github.io/Kraftee/#/

Please forgive any layout issues/unoptimized code, we move very quickly so I often have to wait until I have free time before I can come back and shape it up.

My main issue right now is that while adding items to the cart works, a page refresh is required. This happens with the number that's displayed in the cart icon in the header. It also happens whenever you delete an item from the cart on the cart page, which makes it a very frustrating experience.

However, for this thread, I'd like to mainly focus on getting the number in the cart to update in real-time, since I'll probably be able to apply that code to the other features that need it.


This is the view I'm using for my header. It should already be on the line related to the number of items in the cart:

https://github.com/ClaytonKinder/Kraftee/blob/gh-pages/views/header.html#L8

This is the controller related to the Cart:

https://github.com/ClaytonKinder/Kraftee/blob/gh-pages/js/controllers.js#L20

This is the service/factory related to the Cart:

https://github.com/ClaytonKinder/Kraftee/blob/gh-pages/js/services.js#L56


You can see in the controller where I tried $broadcast to fix the issue, but I don't know how to apply that to the view.

If you have any advice/tips for any other portions of code (HTML, CSS, JS, whatever), please feel free to share them. Any improvement at all is a good thing.

The following method

CartService.addToCart(product);
CartService.deleteFromCart(productId);

Both make a HTTP call and hence are Async. so $rootScope.$broadcast('cart-scanned'); is called even before the CartService.addToCart(product); or CartService.deleteFromCart(productId); has returned.

$scope.addToCart = function (product) {
    console.log('Item added.');
    CartService.addToCart(product);
    // called before the http called returns
    $rootScope.$broadcast('cart-scanned');
  };

  $scope.deleteFromCart = function (productId) {
    console.log('Item deleted.');
    CartService.deleteFromCart(productId);
    // called before the http called returns
    $rootScope.$broadcast('cart-scanned');
  };

Use promises. $q is the service in angular. check out the docs here . Use the following as an example:

In services.js

    .factory('CartService', function ($http, $q) {
        //....
        var addToCart = function (product) {
            var deferred = $q.defer();
            console.log('Added to cart.');
            $http.post(url, product).success(function (resp) {
                console.log(resp);
                deferred.resolve(resp);
            }).error(function (err) {
                console.log(err);
                deferred.reject(err);
            });
            return deferred.promise;
        };

In controllers.js

    $scope.addToCart = function (product) {
      console.log('Item added.');
      CartService.addToCart(product).then(function () {
        $rootScope.$broadcast('cart-scanned');
      });
    };

    $scope.$on('cart-scanned', function () {
      CartService.getCart().success(function (cart) {
        $scope.cart = cart;
      });
    });

CartService.addToCart(product) will return a Promise and the callback passed in the then method is called only after the http call completes.

In the template

    <div ng-controller="CartController" id="cartNumber">
      {{ cart.length }}
    </div>

cart refers to the $scope.cart so you have to update that to in order to update the view.

Please let me know if this doesn't work. You can use the same technique for deleteFromCart .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM