使用原始元素类型的AngularJS指令模板

10

我正在为Angular开发基于UI和排版的指令。在这种情况下,指令被应用的元素是未知的 - 可能是从div、span、h1到h5等任何东西。

使用模板的原因是我可以向其中添加ng-*指令(这样开发人员不需要记住除了指令名称以外的其他内容)。

我尝试向元素添加属性并重新编译,但成功有限。然而,当涉及添加ng-transclude时,没有成功。创建一个新元素并替换旧元素会带来集成问题(忽略可能在元素上的其他指令和数据属性),在将这些属性复制并添加到新元素方面也取得了很少的成功。

这似乎应该非常简单,因为template本身可以将元素更改为您指定的任何内容(使用transcludereplace),那么一定有“冗长的方法”吧?

很遗憾你不能这样做:

module.directive( 'myDir', [ '$window', function( $window ) {
    return {
        restrict: "A",
        controller: function( $scope, $element ) {
            $scope.tag = $element[0].nodeName;
        }
        template: "<{{tag}} data-ng-transclude ng-*=''></{{tag}}>",
        transclude: true,
        replace: true,
        link: function ( scope, element, attrs ) {

        }
    }   
}]);

我认为主要问题在于我想要用模板替换和转移元素,而不是将模板(或编译元素)作为子元素添加。

现在我已经在我的代码中使用原始JS替代了ng-*和模板,例如:

<div data-ng-style="{'font-size':fontSize}></div>

element[0].style.fontSize = scope.fontSize;

这就引出了使用许多ng-*指令的益处的问题。这只是“Angular方式”吗?

1个回答

30

我已经在思考这个问题几周了,直到我意识到template可以是一个能够访问elementattrs的函数。因此,我能够返回一个带有现有元素标签的模板。

module.directive( 'myDir', [ '$window', function( $window ) {
    return {
        restrict: "A",
        template: function( element, attrs ) {
            var tag = element[0].nodeName;
            return "<"+tag+" data-ng-transclude ng-*=''></"+tag+">";
        },
        transclude: true,
        replace: true,
        link: function ( scope, element, attrs ) {

        }
    }   
}]);

HTML

<div data-my-dir>
    <span>some other stuff</span>
    <div>more stuff</div>
</div>

<span data-my-dir></span>

<h1 data-my-dir></h1>

输出

<div ng-*="" data-ng-transclude="" data-my-dir="">
    <span class="ng-scope">some other stuff</span>
    <div class="ng-scope">more stuff</div>
</div>

<span ng-*="" data-ng-transclude="" data-my-dir=""></span>

<h1 ng-*="" data-ng-transclude="" data-my-dir=""></h1>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接