Trying to do something I thought is pretty simple but it's turning out to be pretty annoying. I'm just trying to have a function that runs when you click on a checkbox using the ng-checked directive.
This is the HTML:
<div class="form-group">
<label class="col-sm-2 control-label">Make Payment Optional</label>
<div class="col-sm-4 center-checkbox">
<input type="checkbox"
class="center-checkbox"
ng-model="formData.optionalPayment"
ng-checked="optionalPaymentCheckbox();"
validate-servererror="featured"/>
</div>
</div>
And this is the Angular:
if($scope.formData.optionalPayment === undefined) {
$scope.formData.optionalPayment = TournamentConst.PAYMENT.OPTIONAL;
}
(This check is just for when I load the page for the first time.)
$scope.optionalPaymentCheckbox = function () {
if($scope.formData.optionalPayment === TournamentConst.PAYMENT.OPTIONAL) {
$scope.formData.optionalPayment = TournamentConst.PAYMENT.MANDATORY;
} else {
$scope.formData.optionalPayment = TournamentConst.PAYMENT.OPTIONAL;
}
};
When I load the page, this ng-checked function runs infinitely. Is there something about the ng-checked directive I don't know, or some minor detail or forgot? Thanks in advance.
You are misunderstanding the intention of ng-checked
. What you think it does is "execute this expression when the checkbox is checked" - an event handler directive.
What it actually does is set the checked
property based on the expression. This means it sets up a watch on the expression and evaluates it every digest. If the value changes, it sets or unsets the checked
property accordingly.
In fact, the documentation for ng-checked
says this:
Note that this directive should not be used together with ngModel, as this can lead to unexpected behavior.
As @JB Nizet correctly pointed out, you can achieve the desired effect in your particular case by using ng-true-value
and ng-false-value
and removing ng-checked
altogether.
So your HTML becomes:
<div class="form-group">
<label class="col-sm-2 control-label">Make Payment Optional</label>
<div class="col-sm-4 center-checkbox">
<input type="checkbox"
class="center-checkbox"
ng-model="formData.optionalPayment"
ng-true-value="TournamentConst.PAYMENT.MANDATORY"
ng-false-value="TournamentConst.PAYMENT.OPTIONAL"
validate-servererror="featured"/>
</div>
</div>
Then, in your controller, populate your TournamentConst
object in the scope, so the template can see it:
$scope.TournamentConst = TournamentConst;
(or you can just populate the bits you need)
Finally, get rid of the whole $scope.optionalPaymentCheckbox
function. You will still need the code to set the default value, though.
One last thing: It is confusing that the property is called optionalPayment
, when it is really more like paymentType
, but that is not related to the current problem.