1

I am making an attribute directive that will work similarly to ng-if.

window-match-media="(min-width: 400px)"

which will make the element render if the media query matches and disappear otherwise. I am modeling my directive on the code for ngIf

It works great with the exception that I have to currently enclose the media query in an extra pair of quotes. This is because without it, it seems to try to parse the attribute value. This makes sense for ngIf but in my case I want to simply treat the value as a string.

I see nothing in the ngIf codebase that would allow me to indicate that the value should not be parsed, and adding

  scope: {
    windowMatchMedia: '@',
  },

does not help (I'm not sure attribute directives can isolate scope anyways?).

I access the value via the $attributes parameter to the directive's link function which always does seem to provide it as a string, but if I do not specifically make it one with quotes ie

window-match-media="'(min-width: 400px)'"

I get an error before my directive ever gets a chance to run due to the parsing issue. How do I tell the attribute directive to not parse its value? I don't see anything about this in the $compile docs.

Edit: Here is a Plunkr demonstrating the issue. I should probably open source this after I get it working the way I want and document it

Note how in this example, there is an error in the console

If I surround the attribute in quotes it works because the parser is detecting it as a string. But I don't want the parser involved at all. I want to write a regular ol' attribute value.

I would like the attribute syntax in the first example to work.

4
  • can you please provide plunker for this.. @ should do what you want, angualr will parse only if values are in {{}}, you can look at ng-bind, it does not parse its input Commented Oct 22, 2017 at 3:34
  • @harishr when you do ng-if="foo + 1 == 5" that is not in {{}} and yet it is being evaluated. I'll work on a plunkr but this really is about how directives provide options to the parser (or bypass the parser at all) Commented Oct 22, 2017 at 3:41
  • look at angular.js source code search for ngBindDirective, it doing using stringify and not with isolate scope, not an ideal way though Commented Oct 22, 2017 at 3:45
  • @harishr see the edit - I added two plunker links. One that shows it not working and another that demonstrates that the problem is the attribute needs nested quotation, indicating that the parser is getting itself involved where it is not needed Commented Oct 22, 2017 at 3:52

1 Answer 1

2

The example in the plunk has the problem:

$scope.$watch($attr.windowMatchMedia, windowMatchMediaWatchAction);

The error here is that attribute value is supplied to $scope.$watch - which will result in parsing error if it's not a valid expression.

If directive attribute needs to not be interpolated, it shouldn't be bound to the scope. Instead, $attr.$observe can be used:

$attr.$observe('windowMatchMedia', windowMatchMediaWatchAction);

While

  scope: {
    windowMatchMedia: '@',
  },

is the correct way to do this with one-way binding, although isolated scope puts restrictions on how the directive can be used. It allows to provide window-match-media as an expression and doesn't require to use quotes for strings.

Universal recipe that doesn't put restrictions on the scope yet allows to use expressions in directive attribute involves $attr.$observe.

Then attribute value can be interpolated with $interpolate service against current scope:

var windowMatchMedia = $interpolate($attr.windowMatchMedia)($scope);
$window.matchMedia(windowMatchMedia);
Sign up to request clarification or add additional context in comments.

1 Comment

Wow, thank you! I'm now a bit embarrassed I didn't catch it was that exact line that was breaking things. Would have at least been a clue. Here it is with $observe

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.