动态<svg-icon>作为Angular指令

时间:2017-09-08 15:43:20

标签: javascript angularjs svg

我正在使用精灵中包含的SVG图标,如下所示。

<div class="py-3">
    <svg-icon><src href="sprite.svg#si-glyph-bullet-checked-list"/></svg-icon>
    <span>Tasks</span>
</div>

它工作正常,但当我将其重写为Angular指令时:

app.directive('ngxTileIcon', function () {
    return function (scope, element, attrs) {
        var tileIcon = attrs['ngxTileIcon'];
        var tileCaption = element.text();
        element.text('');
        element.addClass('py-3');
        element.append(
            $('<svg-icon/>').append(
                $('<src/>').attr('href', 'sprite.svg#si-glyph-' + tileIcon)
            ),
            $('<span/>').text(tileCaption)
        );
    };
});

并使用它:

 <div ngx-tile-icon="bullet-checked-list">Tasks</div>

基本上,我得到了相同的标记,但Google Chrome没有显示已将DOM添加到DOM中。使用非Angular方法时,确实如此。最后,使用Angular指令时,不会显示图标。

解决

我刚刚更改了方法 - 我没有将标记添加到元素中,而是直接用html()替换其内容。现在它按预期工作。

app.directive('ngxTileIcon', function () {
    return function (scope, element, attrs) {
        var tileIcon = attrs['ngxTileIcon'];
        var tileCaption = element.text();
        var $tempDiv = $('<div/>');
        element.addClass('py-3');
        $tempDiv.append(
            $('<svg-icon/>').append(
                $('<src/>').attr('href', 'sprite.svg#si-glyph-' + tileIcon)
            ),
            $('<span/>').text(tileCaption)
        );
        element.html($tempDiv.html());
    };
});

2 个答案:

答案 0 :(得分:1)

达米安已经指出这个答案是错误的,但我会留下来防止其他人犯同样的错误!

&LT; SVG-图标&GT;是一个Angular指令而不是本机HTML元素,因此使用jQuery添加它不会触发Angular的逻辑,而你只是没有任何东西。

一般情况下使用Angular 1.x(假设您使用的是1.x?),您应该给它一个模板字段,该字段将根据输入创建图标:

app.directive( "myDirective", function() {
   return {
      template: "<div class='py-3'><svg-icon><src href='sprint.svg#si-glyph-{{ tileIcon }}'></src></svg-icon></div>"
      scope: {
         tileIcon: "<"
      }
   };
});

这应该将“tileIcon”变量绑定到父元素中提供的属性,然后将其注入模板中,并使用数据绑定,以便在父更新时更新。 });

答案 1 :(得分:0)

它不是你要问的,但它可以帮助你解决问题。

看看这个简单的例子,如何使用svg builder with directive。

<button>
   <my-icon   
          icon="arrow_left"  
          size="18" 
          style="fill:#37393B;"></my-icon>
</button>  

<强>指令:

app.directive('myIcon', function () {
    var shapes = {
        'arrow_left':
                'viewBox="-358 231.3 125 133"  >' +
                '<rect x="-342.8" y="262.7" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 -315.0274 678.5285)"  width="89.5" height="22.6"/>' +
                '<rect x="-342.8" y="309.9" transform="matrix(-0.7071 -0.7071 0.7071 -0.7071 -736.0015 337.5721)"  width="89.5" height="22.6"/>' +
              '</svg>'
              //, other svgs
    };

    return {
        restrict: 'E',
        link: function (scope, element, attr) {

            var icon, size;
            var render = function () {
                    icon = attr.icon;
                    var ss = icon.match(/ic_(.*)_([0-9]+)px.svg/m);
                    if (ss !== null) {
                        icon = ss[1];
                        size = ss[2];
                    }

                // size
                if (attr.size !== undefined)
                    size = attr.size;
                else if (size !== null)
                    size = 24;

                // render
                element.html('<svg xmlns="http://www.w3.org/2000/svg"  width="' + size + '" height="' + size + '" x="0px" y="0px" ' + shapes[icon]);
            };
            render();
        }
    };
});

Demo Plunker