Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: ng-src behavior on non-standard attributes?

I'm integrating a media player in my app using the "Video For Everybody" generator. As the player features a fallback to flash if the browser doesn't support HTML5 video and audio I have to build an object element with param attributes with the video and placeholder (image) source.

As expected I run into the classical problem of expressions not being resolved in time, my browser sends requests to my.media.com/{{video.src}} rather then my.media.com/somevideo.mp4

Unfortunately there are several attributes (poster, flashvars, placeholder to name a few) where I face the same problem. How would I go about creating the same behavior as the ng-src or ng-href directives? I tried looking for the relevant source code, but I haven't found it. Here is a snippet which showcases the problematic HTML,

<video controls="controls" poster="{{mediaModel.mediaFile2}}" width="300" height="150">
<source ng-src="{{mediaModel.mediaFile}}" type="{{mediaModel.contentType}}" />
<object type="application/x-shockwave-flash" data="http://player.longtailvideo.com/player.swf" width="300" height="150">
    <param name="movie" value="http://player.longtailvideo.com/player.swf" />
    <param name="allowFullScreen" value="true" />
    <param name="wmode" value="transparent" />
    <param name="flashVars" value="{{'controllerbar=over&amp;image=' + media.mediaFile2 + '&amp;file=' + mediaModel.mediaFile}}" />
    <img ng-src="{{mediaModel.mediaFile2}}" width="300" height="150" title="{{mediaModel.uploadedTime}}" />
</object>

like image 329
Index Avatar asked Nov 14 '13 09:11

Index


3 Answers

You can now use ng-attr-poster, or more generally: ng-attr-whatever.

like image 86
Neil Avatar answered Jan 19 '23 06:01

Neil


Finding the source of build-in directive is made easy on the official API documentation. In this case go to the documentation of ngSrc , at the top of the page you will see two buttons, "Improve this doc" and "View source", click on "View source" and it will automatically take you to the correct source file where the directive is defined. This works across all build-in directive, very handy!

Below I'm pasting the code for ngSrc, which interestingly enough does not look complicated at all, the crucial line seems to be priority: 99, based on the comment next to it means that directives with priority of 99 will run after attributes have been interpolated.

// ng-src, ng-srcset, ng-href are interpolated
forEach(['src', 'srcset', 'href'], function(attrName) {
  var normalized = directiveNormalize('ng-' + attrName);
  ngAttributeAliasDirectives[normalized] = function() {
    return {
      priority: 99, // it needs to run after the attributes are interpolated
      link: function(scope, element, attr) {
        attr.$observe(normalized, function(value) {
          if (!value)
             return;

          attr.$set(attrName, value);

          // on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
          // then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
          // to set the property as well to achieve the desired effect.
          // we use attr[attrName] value since $set can sanitize the url.
          if (msie) element.prop(attrName, attr[attrName]);
        });
      }
    };
  };
});

Given the above it should be trivial to implement your own directive.

like image 21
Beyers Avatar answered Jan 19 '23 05:01

Beyers


So the most generic, maintainable, configurable and reusable solution is to create a custom directive that will handle it for you.

Look at this -->PLNKR<-- there is practically all you need there. You have just to weak it a little bit.

How it works: to the directive you pass the configuration object (if you need more objects just create additional attributes). The element can be in two states: ready or not. And $scope.isReady just states if all the ingredients have been collected. If so ngSwitch loads the videoPlayer template and since all the information is there no unwanted requests are sent.

like image 43
artur grzesiak Avatar answered Jan 19 '23 04:01

artur grzesiak