Checkbox not binding to scope in angularjs

2019-01-08 14:23发布

问题:

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

回答1:

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


回答2:

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



回答3:

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. :)



回答4:

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.