Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS ng-href and svg xlink

I'd like some input on using xml namespaced attributes with angular.

The problem is angular comes with a couple of directives to handle writing attributes such as href and src when angular has parsed the expresssions (otherwise the browser will try to load {{mymodel.myimage}} as a url)

https://github.com/angular/angular.js/blob/master/src/ng/directive/booleanAttrs.js#L329

The problem I'm facing is that I'm using angular to output svg together with D3 and since angular doesn't have a way to output xlink:href I was stuck.

I created a custom directive that outputs xlink:href

app.directive('ngXlinkHref', function () {
  return {
    priority: 99,
    restrict: 'A',
    link: function (scope, element, attr) {
      var attrName = 'xlink:href';
      attr.$observe('ngXlinkHref', function (value) {
        if (!value)
          return;

        attr.$set(attrName, value);
      });
    }
  };
});

Full demo: http://plnkr.co/edit/cMhGRh

But it seems that if I don't manually add xlink:href to the element, the svg image will not render.

Any suggestions on how to best handle xml namespaces / svg together with angular would be greatly appreciated.

like image 278
Leon Radley Avatar asked Apr 09 '13 07:04

Leon Radley


3 Answers

You can use ng-attr-<some attribute>

ng-attr-xlink:href="{{xxx}}" works for me.


Note that you also need an empty xlink:href="" as initial value. – Derek Hsu

like image 92
Derek Hsu Avatar answered Sep 30 '22 06:09

Derek Hsu


If, like me, you're looking for a way to add images to svg, you can do so adding:

xlink:href="" ng-href="{{ foo }}"

Example:

http://jsbin.com/sigoleya/1/edit?html,js,output

Where I found the solution:

https://github.com/angular/angular.js/issues/7697

like image 29
Tiagojdferreira Avatar answered Sep 30 '22 06:09

Tiagojdferreira


I ran into a similar problem when trying to output a value for xlink:href that's tied to the model. Based on the user's chosen <option> in a <select> control, I was trying to show a dynamic SVG icon via the xlink:href attribute of the <use> element.

I found a thread about this in the GitHub Issues for AngularJS. Based on the discussion there, it appears that because a viable workaround exists, they've effectively tabled a fix by moving it to the Backlog milestone.

What ultimately worked for me was inspired by this JSBin:

http://jsbin.com/sigoleya/1/edit?html,js,output

Here's the code I used in my template:

<svg class="icon" data-ng-class="category.iconName">
  <use xlink:href="" data-ng-href="{{'#' + category.iconName}}">
</svg>

Given a category.iconName of icon-music, for example, Angular sets the xlink:href dynamically to #icon-music, which references the <svg id="icon-music"> element further up on the same page.

As others have noted, what's key is setting a blank xlink:href="" attribute on the element where you call the ngHref directive. Attribute order does not seem to matter. Using ng-attr-xlink:href="{{xxx}}" (as mentioned in Derek Hsu's answer) did not work for me.

All of this assumes Angular 1.3.36.

like image 34
Bungle Avatar answered Sep 30 '22 07:09

Bungle