Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$scope.$watch in Angular doesn't work in Ionic/Cordova

I'm building an app using the Ionic Framework for which I now want to create some on-off switches (which are basically fancy styled checkboxes). When a person flips the switch I want to send this to the server, so I'm first trying to catch the switch change event. In a basic angular install I tried it with a simple checkbox in the html (<input type="checkbox" ng-model="theswitch">) and a $watch in my controller like so:

$scope.$watch('theswitch', function(){
    console.log('theswitch changed');
    if ($scope.boel){
        console.log('theswitch is TRUE');
    } else {
        console.log('theswitch IS FALSE');
    }
});

This works like a charm. I now implemented a similar thing in my Ionic app. My HTML is like this:

<ion-item class="item-toggle">
    Mail
    <label class="toggle">
        <input type="checkbox" ng-model="mail">
        <div class="track">
            <div class="handle"></div>
        </div>
    </label>
</ion-item>

and my controller looks like this:

myControllers.controller('AccountCtrl', function ($scope) {
    $scope.$watch('mail', function(){
        console.log('THE MODEL CHANGED');
        if ($scope.mail) {
            console.log('The button was turned ON.');
        } else {
            console.log('The button was turned OFF.');
        }
    });
});

Upon loading the screen I get two logs:

THE MODEL CHANGED
The button was turned OFF.

After that I can flip the switch a million times, but I get no log messages anymore, not even an error. Since it works perfectly in my angular test website, but not in my app, I'm kinda lost in what could be wrong.

Would anybody have any idea what I can do to catch this switch event? All tips are welcome!

like image 891
kramer65 Avatar asked Mar 18 '15 16:03

kramer65


1 Answers

Possible reason for not working $scope.$watch might be property overriding in child scope. If you set $watch on controller scope, but checkbox with ng-model binding is created inside some child scope of the controller, child scope might create its own mail property and controller $scope.$watch will not be able to detect changes in that property. Here is jsfiddle that demonstrates this problem: link.

To avoid this problem you should not use primitive values on the scope for ng-model bindings. Instead you should bind to properties of objects on the scope, for example ng-model="formData.mail" where formData is some object in the controller's scope. To watch for object property changes you also use dot syntax: $scope.$watch('formData.mail', function(){...})

Hope this helps.

like image 153
Stubb0rn Avatar answered Nov 14 '22 23:11

Stubb0rn