Checkbox not binding to scope in angularjs

AngularjsBindingCheckboxCoffeescriptAngularjs Ng-Include

Angularjs 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);
    }
}

DEMO

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionchrisView Question on Stackoverflow
Solution 1 - AngularjsMattView Answer on Stackoverflow
Solution 2 - Angularjszs2020View Answer on Stackoverflow
Solution 3 - AngularjsancajicView Answer on Stackoverflow
Solution 4 - AngularjsRk220View Answer on Stackoverflow