Filter should only be used to format/filter data after Angular has detected that the value to filter has changed. You could of course inject $rootScope into your filter and call $rootScope.$apply() to trigger Angular to call the filter again, but that would be a bit confusing for other developers.
I'd say you have two options. One is to add a run block for your app module that adds a method on the $rootScope which you can call, which listens to resize events and calls $rootScope.$apply().
So you'd do this instead:
<input value="{{responsivize('string')}}" />
The other option is not to put it a run block but make a directive instead which still places the responsivize method on the $rootScope. You'd name the directive and add it to your <body>
.
Basically something like this:
angular.module('app')
.directive('responsivize', function($rootScope) {
return {
restrict: 'A',
link: function(scope, elm, attr){
var showShort = Modernizr && !Modernizr.mq('only all and (min-width: 768px)');
jQuery(window).resize(function() {
var showShort = Modernizr && !Modernizr.mq('only all and (min-width: 768px)');
$rootScope.$apply();
});
$rootScope.responsivize = function(key) {
return key.concat(showShort ? '.short' : '.long');
}
}
};
});
And the HTML:
<body responsivize>
...
</body>
That way it's isolated to that directive, and you can reuse it. Do note that the window resize event might fire a lot of times, so you might want to throttle how many times you call $rootScope.$apply().
A bonus of having it as a method instead of a filter is that the code that calls the method is free to format/use the return value as it wants.