Trying to implement Checkbox and Radio buttons from http://angular-ui.github.io/bootstrap/ but it is very slow (about a second) to react.
Is there something I can do to make it react more quickly? Or another library that does the same thing more reliably?
The demo loads bootstrap ui, and fastclick, which is initialised in one area and not the other. You can see the input fields behave as expected - fast with fastclick, slow without. The toggle buttons behave slowly everywhere.
angular.module('MyApp', ['ui.bootstrap']);
function EditingPageCtrl($scope) {
$scope.radioModelA = undefined;
$scope.radioModelB = undefined;
$scope.fast1 = "this field works quickly, because of fastclick...";
$scope.fast2 = "this field is slow, because no fastclick";
$scope.$watch('radioModelA', function (newValue, oldValue) {
//alert(newValue);
});
}
Internally, the btn-radio
directive is attaching a click handler via JavaScript. FastClick doesn't hijack the touch event and trigger a click because FastClick doesn't support labels. Here is the btnRadio source:
angular.module('ui.bootstrap.buttons', [])
.constant('buttonConfig', {
activeClass:'active',
toggleEvent:'click'
})
.directive('btnRadio', ['buttonConfig', function (buttonConfig) {
var activeClass = buttonConfig.activeClass || 'active';
var toggleEvent = buttonConfig.toggleEvent || 'click';
return {
require:'ngModel',
link:function (scope, element, attrs, ngModelCtrl) {
var value = scope.$eval(attrs.btnRadio);
//model -> UI
scope.$watch(function () {
return ngModelCtrl.$modelValue;
}, function (modelValue) {
if (angular.equals(modelValue, value)){
element.addClass(activeClass);
} else {
element.removeClass(activeClass);
}
});
//ui->model
element.bind(toggleEvent, function () {
if (!element.hasClass(activeClass)) {
scope.$apply(function () {
ngModelCtrl.$setViewValue(value);
});
}
});
}
};
}])
ngTouch hooks into the ng-click
directive. So... it's a little janky, but if you use ngTouch instead of FastClick, you can get improved performance by adding an ng-click
attribute:
<label ng-model="radioModelA" ng-click="radioModelA=true" btn-radio="true" class="btn btn-silver">Yes</label>
<label ng-model="radioModelA" ng-click="radioModelA=false" btn-radio="false" class="btn btn-silver">No</label>
A more elegant solution is to inject btn-radio
's configuration constant and add a touch event:
.config(function(buttonConfig) {
buttonConfig.toggleEvent = 'touchstart click';
});
Use <button>
elements instead of <label>
s and you can use either FastClick or ngTouch to avoid the mobile browser delay.
Also check this out: the vanilla ui-bootstrap demo seems faster than yours, because of the way that it's styled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With