AngularJS: измените элемент, связанный с директивой, используя transclude

Как я могу изменить элемент, связанный с вызовом transclude()?

В моем приложении я динамически загружаю весь SVG-файл с сервера и отображаю его. Мне нужно добавить поведение к загруженному контенту.

В настоящее время у меня есть что-то вроде этого:

<div svg-canvas="urlToSVGContent"></div>

Это загружает тег SVG внутри div. Это прекрасно работает, но что, если я хочу добавить ng-щелчок к каждому <path>, <circle> и т. д.? ng-click уже работает с путями svg из коробки, это просто вопрос ссылки на элемент.

Я уже могу сделать директиву с помощью transclude, которая будет выполняться один раз для каждого пути:

<div svg-canvas="urlToSVGContent">
    <svg-each-path>
        <!-- call transclude once per path found -->
    </svg-each-path>
</div>

Но внутри svg-each-path, хотя у меня есть отдельная область видимости для каждого элемента, параметр el директивы не имеет смысла. Или он все еще указывает на родительский div или что-то в этом роде.

Я хотел бы сделать это:

<div svg-canvas="urlToSVGContent">
    <svg-each-path ng-click="onPathClick()">
    </svg-each-path>
</div>

Вот как svg-each-path выглядит сейчас:

function svgEachPath() {
    return {
        restrict: 'E',
        transclude: 'element',
        priority: 1000,
        terminal: true,
        link: link,
    }    

    function link(scope, el, attrs, ctrl, $transclude) {
        // scope.paths was set by the svg-canvas directive
        scope.paths.forEach(function(path) {
            var childScope = <InnerScope> scope.$new()
            childScope.path = path

            // how can I change "el" to point to path?
            // or get the clone to be a clone of the path instead of the parent element?
            $transclude(childScope, function(clone) {

            })
        })
    }
}

person Sean Clark Hess    schedule 10.02.2014    source источник
comment
как насчет использования replace: true? (при условии, что шаблон имеет один корневой элемент). таким образом el будет указывать на фактический элемент пути в каждой области.   -  person Eliran Malka    schedule 10.02.2014
comment
Там нет шаблона. Я загружаю динамический SVG-контент, а затем хочу добавить поведение к каждому найденному внутри него тегу <path>. Я не могу предсказать пути, которые будут в контенте.   -  person Sean Clark Hess    schedule 10.02.2014
comment
Это похоже на то, что я хочу, чтобы svg-each-path был прокси-тегом для реальных path тегов, найденных в контенте.   -  person Sean Clark Hess    schedule 10.02.2014
comment
вот почему я предложил это. если вы замените корневой элемент для каждого svg-each-path, вы получите ссылку на элемент path в функциях связывания/компиляции.   -  person Eliran Malka    schedule 10.02.2014


Ответы (1)


Я искал службу $compile. Он позволяет вам взять любую строку или элемент html и привязать его к области действия для запуска директив. Он вообще не требует трансклюзивности.

function svgEachPath($compile) {
    return {
        restrict: 'E',

        // should stop processing directives. we don't want ng-click to apply to the fake element
        terminal: true,
        priority: 1000,

        link: link,
    }    

    function link(scope, el, attrs) {
        scope.paths.forEach(function(path) {
            // copy in all my attributes to the element itself
            Object.keys(attrs)
            .filter((key) => key[0] != "$")
            .forEach((key) => {
                // use snake case name, not camel case
                path.attr(attrs.$attr[key], attrs[key])                
            })

            // "compile" the element - attaching directives, etc
            var link = $compile(path)
            link(scope)
        })
    }
}

Применение:

<div svg-canvas="urlToSVGContent">
    <svg-each-path ng-click="onPathClick(...)">
    </svg-each-path>
</div>
person Sean Clark Hess    schedule 10.02.2014