Angular : Update model from directive

Problem

I have a fiddle up here: http://jsfiddle.net/KdkKE/44/

What I’d like to do create a ‘toggle’ component, basically a custom checkbox but with html that changes if it is true or false, which is bound to a boolean in a controller.

When the user clicks on the toggle the model is updated the directive’s view changes. It’s similar to the examples at the end of the directives doc http://docs.angularjs.org/guide/directive but the state would be bound so that it would be correct on startup.

var app = angular.module('App', []);

function Ctrl($scope) {
$scope.init = function() {
$scope.foo = true
}
}

app.directive('toggle', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
label: '@',
ngModel: '='
},
template:
'<div style="cursor: hand; cursor: pointer">{{label}}: {{ngModel}}</div>',
link: function(scope, element, attrs, controller) {
element.bind('click', function() {
scope.ngModel = false;
attrs.$set('ngModel', false);
console.log('plz', attrs.ngModel);
});
}
};
});

-

<div ng-app="App">
<div ng-controller="Ctrl" ng-init="init()">
<p>Foo in Ctrl: {{foo}}</p>
<toggle label="Foo" ng-model="foo"></toggle>
</div>
</div>

Problem courtesy of: kreek

Solution

I think you are just missing the use of $apply. See it working here: http://jsfiddle.net/4TnkE/

element.bind('click', function() {
scope.$apply(function() {
scope.ngModel = !scope.ngModel;
});
});

It can also be used like this to avoid nesting in another function:

element.bind('click', function() {
scope.ngModel = !scope.ngModel;
scope.$apply();
});

Solution courtesy of: Jay Querie

View additional discussion.

Like what you read? Give Angular.js Recipes a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.