Q:

customized directive controller data sync with factory data

I am new to angularjs. I found the following example somewhere, its working fine. However, I don't understand how the data in the customized directive controller sync up with the factory data. Here is the code:
angular.module("cart",[]).factory("cart", function(){
   var cartData = [];
   return{
     addProduct:function(id, name, price){
       cartData.push({count:1, id:id, price:price, name:name})
     },
     getProduct: function(){
       return cartData;
     }
   };
}).directive("cartSummary", function(cart){
    return{
      restrict: "E",
      template:"cartSummary.html",
      controller: function($scope){
        var cartData = cart.getProduct();

        $scope.totalPrice = function(){
          var total = 0;
          for(var i=0; i<=cartData.length; i++){
            total+= (cartData[i].price * cartData[i] * count);
          }
        }
      }
    }
});

and in another module, I have the following code to update the cartData:
angular.module("store", ["cart"]).controller("storeCtrl", function($scope, cart){
  /*some logic here*/
  $scope.addToCart = function(){
    cart.addProduct(product.id, product.name, product.price);
  }
});

Here is the view:
<html ng-app="store">
   <body ng-controller="storeCtrl">
     <!--some html-->
     <cart-summary/>
     <!--some html-->
     <button ng-click="addToCart(item)">Add To Cart</button>
   </body>
</html>

The template of directive: 
 <div class="navbar-text">
    {{totalPrice()}}
 </div>

I understand the cartData in the factory will get updated every time user clicks the "Add to Cart" button, but I don't get the magic behind the fact of cartData in the factory always sync up with the data in the customized directive controller. How does the function $scope.totalprice() get called every time?
Can someone explain this to me? Thank you so much!

A:

It's actually very simple. In javascript, all objects, arrays, and functions we use are actually used by reference, while the other data types are used by value.
It doesn't matter that you called a getter to get the reference of the object, what does matter is that it is in fact a reference and not the object itself, so when you add a new item you are adding it to the unique source of data.
Try this, on your directive put this code inside a new method and execute it having $scope.cartData as the reference you use on the view:
$scope.cartData = {}; //you are destroying the reference but not the real object
$scope.cartData = cart.cartData; //you will get all your items back on play as it refreshes the reference with the original one

With {{totalPrice()}} everything changes, here angular doesn't know if the result of the totalPrice function could change between two different digest cycles, so the framework must reexecute the function on each cycle to check.
In order not to make the application perform poorly, this kind of interpolations should be avoided, as they are considered a bad practice, specially if the function has heavy logic inside of it. The way to fix this is to precalculate the result of the function and assign it to a new attribute inside the scope, and make the interpolation listen to that attribute instead of executing a function.
Hope this explanation helps!
Cheers!

