为什么在AngularJS指令中不推荐使用“替换”属性?

根据 API 文档,指令的属性已被弃用,因此将来,所有指令都将以当前的默认值 .replacereplace: false

这消除了开发人员替换元素指令元素的能力,而此功能没有明显的替代功能。

有关元素指令如何使用和不带 元素指令的示例,请参阅此 plunkreplace: true

为什么这个有用的属性被弃用而没有替换?


答案 1

更新

其中一位合作者表示,它不会被删除,但已知的错误不会得到修复。https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb#commitcomment-8124407

源语言

以下是此更改的提交:https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb

用于定义指令以替换它们所在的元素的标志将在下一个主要角度版本中被删除。此功能具有困难的语义(例如,如何合并属性),并且与它解决的问题相比,会导致更多问题。此外,对于WebComponents,在DOM中具有自定义元素是正常的。replace

在我看来,这是维护支持的复杂性与收益的结合。

显然,dev使用它的一个原因是他们更喜欢注入语义正确的标记,从而取代了自定义指令标签。


阅读该链接下方的评论,显然很多人都希望它留下来。


答案 2

如果您担心在下一个版本中会将其删除,则可以使用函数来复制该行为。replace: truepostCompile

/// Replace element with it's first child
Utils.replaceWithChild = function(element) {
    var child = angular.element(element[0].firstChild);
    Utils.mergeAttributes(element, child);
    element.replaceWith(child);
}

/// Copy attributes from sourceElement to targetElement, merging their values if the attribute is already present
Utils.mergeAttributes = function(sourceElement, targetElement) {
    var arr = sourceElement[0].attributes;
    for(var i = 0; i < arr.length; i++) {
        var item = arr[i];
        if(!item.specified)
            continue;

        var key = item.name;
        var sourceVal = item.value;
        var targetVal = targetElement.attr(key);

        if(sourceVal === targetVal)
            continue;

        var newVal = targetVal === undefined
            ? sourceVal
            : sourceVal + ' ' + targetVal;

        targetElement.attr(key, newVal);
    }
}

angular.module('test')
.directive('unwrap', function() {
    return {
        restrict: 'AE',
        templateUrl: 'unwrap.part.html',
        compile: function() {
            return function postCompile(scope, element, attr) {
                Utils.replaceWithChild(element);
            };
        }
    }; 
});