If this vm.selecionaFiltros
function is called automatically, the possible problem is that it is happening outside the scope of AngularJs
.
What does this mean?
It means that digest cycle
has passed, so the changes will not be applied. digest cycle
is a process of AngularJs
(also known as dirty checking ) that compares all bindings through watchers
( {{meuEscopo}}
or ng-bind="meuEscopo"
- each element of this in your view generates a new watcher
) to check if that data has changed and, if so, update the view
with this new value.
If your function runs after digest cycle
means that no matter how much the changes occur AngularJs
does not yet "know" it.
When digest cycle
is triggered?
They are always fired when the application loads or through interactions with AngularJS functions, for example, ngClick
, ngChange
, ngBlur
, etc. Or, within controller
or directive
, using $timeout
(which is what you are doing) and $interval
, and finally through a manual call, explained better below.
How to resolve?
The way to resolve this would be by manually calling digest cycle
.
There are 2 methods to get the same end result:
-
$scope.$digest()
-
$scope.$apply()
Both are similar and will give you the same end result. However, $scope.$apply()
will trigger the $rootScope.$digest()
event that affects all scopes and their child elements while $scope.$digest()
affects only the local scope and its child elements, giving you a better performance, as it will not affect the application as a whole.
Simple example, assuming that in the same view as this ng-repeat
you have a directive
that shows the weather, it has no connection to that list and has its own scope, since it comes from a directive
. If you call $scope.$digest()
, digest cycle
will not check the watchers
that belongs to it, so you have more performance. But if you call $scope.$apply()
, how it will fire $rootScope.$digest()
instead of $scope.$digest()
- that is, the global cycle, that climate directive and all your watchers and child too will be validated by the cycle.
When to use one or the other?
If you are sure that the called function will only affect values that are within that scope, call $scope.$digest()
. But if you know that interaction with these functions can interfere with scopes that are out of the current range, use $scope.$apply()
.
Example: Assuming this list of ng-repeat
is to select which type of temperature is displayed in directive
. Celsius , Kelvin or Fahrenheit , so if I click on one of these elements of ng-repeat
, I need to change an element outside my scope, so I call $scope.$apply()
.
So, your code looks like this:
vm.selecionaFiltros = function(){
$('.marcas').iCheck({
checkboxClass: 'icheckbox_minimal',
radioClass: 'iradio_minimal',
});
$('.marcas').on('ifChanged', function (event) {
console.log('1');
$scope.$digest(); //aqui
});
$scope.$digest(); //ou aqui
}
If you want, you can still remove the function declaration using vm
and use a simple JS
function.
function selecionaFiltros() {
[...]
}
//chamada da função
selecionaFiltros();
The vm
at the front serves to execute a function that is called through the view , with ng-click
, ng-blur
, etc ..
Note : Just to remember, since you're using syntax
of vm
, you need to inject $scope
before you can use it.