【问题标题】:AngularJS : Change the element associated with directive using transcludeAngularJS:使用 transclude 更改与指令关联的元素
【发布时间】:2014-02-10 15:33:26
【问题描述】:

如何更改与对transclude() 的调用关联的元素?

在我的应用程序中,我从服务器动态加载整个 SVG 文件并显示它。我需要向加载的内容添加行为。

目前,我有这样的事情:

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

这会在 div 中加载一个 SVG 标记。这很好用,但是如果我想为每个&lt;path&gt;&lt;circle&gt; 等添加一个 ng-click 怎么办? 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) {

            })
        })
    }
}

【问题讨论】:

  • replace: true怎么样? (假设模板有一个根元素)。这样el 将指向每个范围内的实际路径元素。
  • 没有模板。我正在加载动态 SVG 内容,然后我想为其中的每个 &lt;path&gt; 标签添加行为。我无法预测内容中的路径。
  • 这有点像我希望svg-each-path 成为内容中真实path 标签的代理标签。
  • 这就是我建议它的原因。如果您替换每个 svg-each-path 的根元素,您将在链接/编译函数中获得对 path 元素的引用。

标签: javascript angularjs angularjs-directive transclusion


【解决方案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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多