dor.elmaliach
dor.elmaliach

Reputation: 535

angular custom attribute directive should be replaced by another directive

I an trying to implement a custom attribute directive for a src-like attribute, that should represent a relative path to a directory.

The path to the directory is in a global variable (say mydir).

The attribute should be replaced with an ng-src combined with the directory path.

I want to use it like this:

<md-icon my-src="cake.svg"></md-icon>
<md-icon my-src="{{ anExpression }}"></md-icon>
<md-icon my-src="{{::onTimeBinding}}"></md-icon>

I also want to support this not just for angulat material use.

Thanks for the help!

Edit:

I am sorry I didn't explain my self well. I want to support the use of the mySrc directive in all kinds of elements. It should be replaced as ng-src with the base directory. I created a plunkr but it doesn't work. The code looks like this so far:

app.directive("mySrc", function() {

  return {
    restrict: "A",
    compile: function(element, attrs) {

      return {
        pre: function(scope, element, attributes) {
          var baseUrl = 'http://dummyimage.com/';
          attributes.$set("ng-src", baseUrl + attributes.mySrc);
        }
      }

    }
  }
});

Example of use:

<img my-src="100" />
<img my-src="{{ expr }}" />
<img my-src="{{:: oneTimeExpr }}" />

It is important for us to support the last two options also.

Upvotes: 0

Views: 158

Answers (2)

Claies
Claies

Reputation: 22323

Your directive actually works, but your approach is slightly off. You don't want to change my-src to ng-src, since ng-src is a directive that does something similar to what you are trying to do. What you actually want to do is change my-src to src, so the browser can actually render the tag.

In other words, attributes.$set("src", baseUrl + attributes.mySrc); does what you want. However, it's not dynamic.

Taken from the source for ng-src, you can use $observe to monitor your attribute for changes.

pre: function(scope, element, attributes) {
    var baseUrl = 'http://dummyimage.com/';
    attributes.$observe("mySrc", function(value) {
        attributes.$set("src", baseUrl + attributes.mySrc);
    })
}

<button ng-click="expr = '200'">Test dynamic</button>

I just added a quick button to test the dynamic change. With $observe, any time the mySrc attribute changes, the src attribute will be updated with the new URL.

http://plnkr.co/edit/vogwUGai8iMavk5elDVB?p=preview

Upvotes: 2

Subash
Subash

Reputation: 7266

You can perform your required action in the directive implementation:

var app = angular.module('app', []);

app.directive('mySrc', function ($compile) {
    return {
        restrict: 'A',
        replace: true,
        scope: true,
        template: '<li><img ng-src="{{ image }}" /></li>',
        link: function (scope, element, attrs) {
          var baseUrl = 'http://dummyimage.com/';
          console.log(attrs);

          scope.image = baseUrl + attrs.mySrc;
        }
    };
});

Here is the working plunkr

Upvotes: 1

Related Questions