Reputation: 4237
I make heavy use of this trick
ng-if="::vm.isLoaded || undefined"
In this case, if vm.isLoaded
is anything falsey the watch will continue to operate because undefined
is always returned in that case, and the "one time binding" continues to watch until the expression evaluates to something other than undefined
.
Is there any way to achieve the reverse? Ie keep watching truthy values until the expression evaluates to undefined
, or some other "magic" value.
A real use case is a Loading... gif, which once the content is loaded, needs to disappear.
ng-if="!vm.isLoaded"
works fine (shows the loading gif while loading, and hides it once loaded), but once the stuff is loaded, I want the watch to be removed (the stuff will never become "unloaded" again).
Upvotes: 1
Views: 225
Reputation: 48211
Copying over from GitHub:
Negative ngIf
with one-time binding is indeed not possible currently and is a usecase (the only one afaik) that makes ngUnless
(the opposite of ngIf
) enable something that is not already possible.
A more verbose work-around for achieving what you want is to use ngSwitch
(although this adds an extra DOM element - which you can hide of course).
<div ng-switch="::(foo || undefined)">
<div ng-switch-when="undefined">
This text will be removed for ever,
once `foo` evaluates to something truthy
</div>
</div>
That said, ngIf
is just a plain old directive (and not a complex one for that matter), so it is not difficult to copy and modify its source code and include it in your app.
Here is an "ngUnless"-like demo.
Upvotes: 1
Reputation: 4237
ng-hide="::vm.isLoaded || undefined"
This doesn't directly answer the question, because I really wanted to use ng-if
to remove the loading gif from the DOM altogether.
But hiding it and removing the watch is the next best thing. I'm not sure of the relative performance issue of accumulating dead hidden DOM elements vs accumulating dead watches.
What I really need is a negative version of ng-if
. Like ng-notif
. :P
Upvotes: 0
Reputation: 18647
$watch returns a deregistration function.
You can unregister
a $watch
with the function returned by the $watch
call:
var unwatch = $scope.$watch('isLoaded', function(newValue, oldValue) {
if(newValue == false || newValue == undefined)
{
unwatch();
}
});
So, once your isLoaded
becomes false
or undefined
, the watch
on it is removed.
Upvotes: 0