2013-09-19 2 views
1

У меня есть две директивы: my-svg и my-rect. Я хочу, чтобы использовать их как это:AngularJS, создающий HTMLElements вместо SVGElements

<svg my-svg> 
     <my-rect/> 
    </svg> 

my-rect создает SVG rect и my-svgsvg создает узел с прямоугольником внутри включены через. В конце концов, что я хочу, чтобы это:

<svg width='300' height='300'> 
     <rect x="140" y="30" width="25" height="25" fill="red"></rect> 
    </svg> 

Смотрите пример здесь: http://plnkr.co/edit/UIyUtX?p=preview

Как вы можете видеть, не отображается красный прямоугольник, даже если она существует в DOM. Согласно этому discussion, кажется, что прямоугольник не отображается, потому что это HTMLElement, когда он должен быть SVGElement.

Как было предложено в этом же обсуждении, я использую специальный компилятор директивы для преобразования узлов DOM из типа HTMLElement в SVGElement, но даже это не работает в моем случае использования.

Что я делаю неправильно?

Благодаря

ответ

0

Под капотами AngularJS использует JQuery или JQLite для создания элементов из шаблонов для замены.

JQuery и JQLite оба используют document.createElement, а не document.createElementNS с правильным пространством имен SVG.

В вашей директиве вам необходимо взять на себя создание элементов SVG от AngularJS.

Вы можете вводить следующую вспомогательную функцию в вашу директиву:

.value('createSVGNode', function(name, element, settings) { 
    var namespace = 'http://www.w3.org/2000/svg'; 
    var node = document.createElementNS(namespace, name); 
    for (var attribute in settings) { 
    var value = settings[attribute]; 
    if (value !== null && !attribute.match(/\$/) && (typeof value !== 'string' || value !== '')) { 
     node.setAttribute(attribute, value); 
    } 
    } 
    return node; 
}) 

И использовать его в функции связи, а не с помощью шаблона (либо внешний или встроенный) - что-то вроде:

link: function(scope, element, attrs) { 
    var cx = '{{x}'; 
    var cy = '{{y}}'; 
    var r = '{{r}}'; 
    var circle = createSVGNode('circle', element, attrs); 

    angular.element(circle).attr('ng-attr-cx', cx); 
    angular.element(circle).attr('ng-attr-cy', cy); 
    angular.element(circle).attr('ng-attr-r', r); 
    element.replaceWith(circle); 

    $compile(circle)(scope); 
} 

Вы можете увидеть пример этой работы - в контексте пикчарта - на https://github.com/mjgodfrey83/angular-piechart/.

Исправление приземлилось в угловом 1.3.0-beta8, чтобы можно было указывать типы шаблонов без html - см. here. Например, пример использования angular-charts.

Надеюсь, что это поможет.

0

Ввод

<g> 
    <my-rect></my-rect> 
</g> 

отобразит прямоугольник. Он не отвечает на вопрос, что вы делаете неправильно, но он получает код для отображения того, что вы хотите. Я потратил некоторое время на эту проблему самостоятельно, но я не мог заставить ее работать, и поэтому решил проблему по-другому. В чем проблема, которую вы пытаетесь решить с помощью этого метода?

Смежные вопросы