EdwardJPayton EdwardJPayton - 8 days ago 7
AngularJS Question

How to keep a total between AngularJS Components in ngRepeat

Here's the problem - a limited number of licences can be assigned to users, when the available number is 0 no more can be assigned and other buttons will be disabled. Licences can removed and reassigned.

The list of users is in an ngRepeat loop, and the assign / remove licence function is in a component. When I click the assign / remove button it updates itself and the total, but the button in other components don't update until the next click.

Here's the full code of what I have so far: http://plnkr.co/edit/T4soR8qpSAzY0cANknsE?p=preview

The HTML:

<body ng-controller="RootController as root">
<pre>qty: {{ root.qtyAvailable }} / {{ root.qtyMax }}</pre>
<div ng-repeat="user in root.users | orderBy: 'firstname' ">
{{ user.firstname }}
<assign
has-licence="user.hasLicence"
reassignable="user.reassignable"
qty="root.qtyAvailable"
qty-max="root.qtyMax"
></assign>
</div>
</body>


The controller and component:

.controller('RootController', function() {
this.qtyMax = 2;
this.qtyAvailable = 1;

this.users = [
{firstname: 'john', hasLicence: false, reassignable: true},
{firstname: 'jane', hasLicence: false, reassignable: true},
{firstname: 'joey', hasLicence: false, reassignable: true},
{firstname: 'bob', hasLicence: true, reassignable: true},
];

})

.component('assign', {
template: `<button ng-click="$ctrl.click($ctrl.hasLicence)">{{ $ctrl.text }}</button>`,
controller: function() {
this.text = '';

// set the button text
this.buttonText = function() {
if(this.hasLicence) {
this.text = 'remove';
}
else if(!this.hasLicence && this.reassignable && this.qty>0) {
this.text = 'assign';
}
else {
this.text = '-'; // eg button disabled
}
}

this.buttonText();

// click function
this.click = function(licence) {
if(licence === true) {
this.hasLicence = false;
this.qty++
}
else if(this.qty>0) {
this.hasLicence = true;
this.qty--
}
this.buttonText(this.hasLicence);
console.log(this.qty)
}

},
bindings: {
hasLicence: '<',
reassignable: '<', // not relevant for this demo
qty: '=',
qtyMax: '<'
}

});

Answer

Something like this:

  template: `<button ng-disabled="$ctrl.qty <= 0 && !$ctrl.hasLicence" ng-click="$ctrl.click($ctrl.hasLicence)">{{ $ctrl.text }}</button><span ng-if="$ctrl.qty <= 0 && !$ctrl.hasLicence">No licenses are free</span>`

Using extendend syntax : ng-disabled="$ctrl.qty <= 0 && !$ctrl.hasLicence" for only disabling the buttons to add a license when the 'free licenses' var is <= 0.

Updated Plunkr