Reputation: 310
I wanted to create an own checkbox input control. It should behave just like <input type="checkbox" ng-model="check" ng-change=”handler()”>
with a different look. I created a custom directive with an isolated scope and instead of ng-model
I used binding ‘=’ between the directive’s and the controllers’s scope variable and instead of ng-change
I used binding ‘&’ between the directive’s on-click handler and a controller’s scope method (handler).
.controller('MyCtrl', ['$scope', function MyCtrl($scope) {
$scope.check = false;
$scope.messages = [];
$scope.onCheckChange = function(value) {
$scope.messages.push('onCheckChange: $scope.check == ' + $scope.check + ' value == ' + value);
}
}])
.directive('myCheckbox', function() {
return {
restrict: 'A',
scope: {
title: '@',
value: '=',
onChangeHandler: '&'
},
template:
'<span class="my-checkbox"> ' +
'<span class="tickbox" ng-click="click()" ng-class="{\'ticked\': value}" title="{{title}}"></span>' +
'</span>',
link: function(scope, element, attrs) {
scope.click = function() {
scope.value = ! scope.value;
scope.onChangeHandler({value: scope.value});
};
}
};
})
A working plunk is here http://plnkr.co/edit/oIQbqSzcWUShfdTyDBTl?p=preview.
Things work as I would expect with one exception:
scope.click()
is called which sets scope.value
to the new checkbox value and sends this new value as a parameter to the controller’s $scope.onCheckChange()
$scope.onCheckChange()
the $scope.check
variable does not contain the new value, but the previous one, although the parameter ‘value’ is the new value already.$scope.check
variable set to the new value. It seems, that the call from the on-click()
is somehow ‘faster’ than the Angular data binding. I have thought about scope.$apply but don’t think this is the case - Angular takes care of the binding nicely but it takes time until it bubbles through… ng-model
, ng-change
or ng-disable
? I would like to approach custom directives the same way as the native ones. Or is it just names of the bindings?Upvotes: 1
Views: 958
Reputation: 711
Use ngModel http://plnkr.co/edit/IPWhZ8?p=preview
Your problem was because your handler was triggered before digest cycle finished updating $scope.check.
Upvotes: 0
Reputation: 310
I still don't know why is it happening, but I've found a workaround: to wrap the handler to a $timeout
block without specific delay. It does not matter if it is the handler of the directive or the handler in the controller, both do the trick. The $timeout
gives angular time to bubble the binding through.
Anyway, I am still curious why it is like this.
Upvotes: 0