Checkbox not binding to scope in angularjs
AngularjsBindingCheckboxCoffeescriptAngularjs Ng-IncludeAngularjs Problem Overview
I am trying to bind a checkbox to scope using ng-model. The checkbox's initial state corresponds to the scope model just fine, but when I check/uncheck the checkbox, the model does not change. Some things to note is that the template is dynamically loaded at runtime using ng-include
app.controller "OrdersController", ($scope, $http, $location, $state, $stateParams, Order) ->
$scope.billing_is_shipping = false
$scope.bind_billing_to_shipping = ->
console.log $scope.billing_is_shipping
<input type="checkbox" ng-model="billing_is_shipping"/>
When I check the box the console logs false, when I uncheck the box, the console again logs false. I also have an order model on the scope, and if I change the checkbox's model to be order.billing_is_shipping, it works fine
Angularjs Solutions
Solution 1 - Angularjs
I struggled with this problem for a while. What worked was to bind the input to an object instead of a primitive.
<!-- Partial -->
<input type="checkbox" ng-model="someObject.someProperty"> Check Me!
// Controller
$scope.someObject.someProperty = false
Solution 2 - Angularjs
If the template is loaded using ng-include
, you need to use $parent
to access the model defined in the parent scope since ng-include
if you want to update by clicking on the checkbox.
<div ng-app ng-controller="Ctrl">
<div ng-include src="'template.html'"></div>
</div>
<script type="text/ng-template" id="template.html">
<input type="checkbox" ng-model="$parent.billing_is_shipping" ng-change="checked()"/>
</script>
function Ctrl($scope) {
$scope.billing_is_shipping = true;
$scope.checked = function(){
console.log($scope.billing_is_shipping);
}
}
Solution 3 - Angularjs
In my directive (in the link function) I had created scope variable success like this:
link: function(scope, element, attrs) {
"use strict";
scope.success = false;
And in the scope template included input tag like:
<input type="checkbox" ng-model="success">
This did not work.
In the end I changed my scope variable to look like this:
link: function(scope, element, attrs) {
"use strict";
scope.outcome = {
success : false
};
And my input tag to look like this:
<input type="checkbox" ng-model="outcome.success">
It now works as expected. I knew an explanation for this, but forgot, maybe someone will fill it in for me. :)
Solution 4 - Angularjs
Expanding on Matt's answer, please see this Egghead.io video that addresses this very issue and provides an explanation for: Why binding properties directly to $scope can cause issues
see: https://groups.google.com/forum/#!topic/angular/7Nd_me5YrHU
> Usually this is due to another directive in-between your ng-controller
> and your input that is creating a new scope. When the select writes
> out it value, it will write it up to the most recent scope, so it
> would write it to this scope rather than the parent that is further
> away.
>
> The best practice is to never bind directly to a variable on the scope
> in an ng-model
, this is also known as always including a "dot" in
> your ngmodel.