How to avoid reentrancy in AngularJS?

149 views Asked by At

Bootstrap selectpicker hides original select and creates additional element filling it with options from the select. However when using ngOptions selectpicker doesn't automatically updates itself.

So I've created a directive which listens for ngOptions collection changes and calls element.selectpicker()

It works fine if no filtering is applied for ngOptions. Otherwise filering function returns new array each time it is called what causes $watch callback to fire which recreates selectpicker. Angular detects DOM has changed and starts new digest cycle effectively infinitely looping the process. After 10 iterations Angular as expected throws exception.

I need to temporarily unsubscribe from the watch when creating selectpicker und later subscribe again when digest cycles are finished. Is it possible?

Update1

Thougt a little more and now have an Idea to try. Filter defines a factory returning filtering function thus I can use captured array to store filtered content - the reference won't change so listener will fire only when contents of collection changes.

1

There are 1 answers

0
vp_arth On

About temporarily stop watching:

$watch always returns you unwatch function afaik:

var stopW = $scope.$watch('data', process);
stopW(); //anywhere

Also small advice. Sometimes you don't want to compare '===' when watching.
Try to use function, detects anything changed:

$watch(function(){return $scope.data.list;}, process);

or even:

$watch(function(){return JSON.stringify($scope.data);}, process);

The last one should completely ignore array recreates by your filter.