Reputation: 647
Is there a way to re-render AngularJS filters? I am trying to use the angular currency filter that displays the currency symbol based on the language file that's loaded. I need to re-render the filters once I programmatically load the appropriate language file.
Upvotes: 5
Views: 3232
Reputation: 2552
From Angular 1.3 filters are stateless which means filters just will update when theirs input have change.
If you want to update your filter ever, you need to make your filters $stateful.
app.filter('translate', translate);
translate.$inject = ['$rootScope'];
function translate($rootScope){
filter.$stateful = true;
return filter;
function filter(str) {
return i18n[$rootScope.currentLang][str];
};
}
Filters will execute on each $digest but this is inadvisable by perfm.
Upvotes: 5
Reputation: 2492
The Developer Guide/Filters documentation says:
In templates, filters are only executed when their inputs have changed.
So, if we want the filter to be stateless, but responding to changes of some external state, we should make this state to be an input to the filter. This input can be purely virtual, not having anything to do with the internal logic of the filter, only triggering its execution.
I have recently faced this problem figuring out how to dynamically re-render moment.js output on a locale change event. This is my filter function:
function FromNowFilter($moment) {
return function (value, langKey, omitSuffix) {
//langKey parameter is only used for triggering an update when language is changed
return $moment(value).fromNow(omitSuffix);
}
}
Upvotes: 0
Reputation: 13681
Yes. For each expression on your template there is a $watch setup. The filters are part of this $watch evaluation, so you just need to trigger a digest cycle. After you load your language file just make sure to call $scope.$apply(), which will re-run all your watches and update your template if the end-result of any watch has changed.
Upvotes: 0