Estoy tratando de implementar un carrito de compras simple para libros de dos maneras: (1) enfoque de módulo y controlador y (2) enfoque de módulo y componente. Usé $scope.watch en el primero, por lo que el código funciona. Pero parece que no puedo implementarlo en la segunda parte.
(1) -HTML:
<body ng-controller="CartControler" ng-init="updateTotal()">
<table>
<caption><b>My Books</b></caption>
<thead>
<tr>
<th>Title</th>
<th>Qty</th>
<th>$UnitPrice</th>
<th>Line Total</th>
<th>Total {{total | currency}}</th> //displays the correct amount
</tr>
.....
(1) - JS:
angular.module('myApp', [])
.controller('CartControler', function ($scope) {
$scope.books = [
{title: 'Absolute Java', qty: 1, price: 114.95},
{title: 'Pro HTML5', qty: 2, price: 27.95},
{title: 'Head First HTML5', qty: 1, price: 27.89}
];
$scope.total;
$scope.updateTotal = function(value) {
$scope.total = 0;
for(v in value){
$scope.total += value[v].price * value[v].qty;
}
return $scope.total;
}
$scope.$watch('books', function() {
$scope.updateTotal($scope.books);
}, true)
(2) -HTML:
<table>
<caption><b>My Books</b></caption>
<thead>
<tr>
<th>Title</th>
<th>Qty</th>
<th>$UnitPrice</th>
<th>Line Total</th>
<th>Total {{$ctrl.total | currency}} </th> //displays correct amount
but does not update on adding/removing/editing books
</tr>
</thead>
<tbody >
....
(2) - JS:
angular.module("cartApp")
.component('cartList', {
templateUrl: 'cart-list/cart-list.template.html',
init: 'updateTotal()',
controller: function CartListController() {
this.books = [
{title: 'Absolute Java', qty: 1, price: 114.95},
{title: 'Pro HTML5', qty: 2, price: 27.95},
{title: 'Head First HTML5', qty: 1, price: 27.89}
];
this.total;
this.updateTotal = function(value) {
this.total = 0;
for(v in value){
this.total += value[v].price * value[v].qty;
}
return this.total;
}
this.total = this.updateTotal(this.books);
En la primera implementación, la función updateTotal se invoca en la inicialización, porque tiene ng-init en HTML. En la segunda implementación, updateTotal nunca se invoca y esta es la razón por la que no funciona. $watch se activa solo cuando cambia la lista de libros. En tu caso no. Cuando se agregará un libro adicional en tiempo de ejecución, la detección de cambios activará el observador y llamará a la función updateTotal. Para trabajar con la segunda implementación desde el principio, agregue esta línea de código:
this.total = this.updateTotal();