为什么在AngularJS指令中不推荐使用`replace`属性?

sbl*_*eon 108 javascript angularjs angularjs-directive

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

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

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

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

Les*_*sar 70

UPDATE

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

原版的

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

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

这听起来像是复杂性与利益的结合,以维持支持.

显然开发人员使用它的原因之一是因为他们更喜欢注入语义正确的标记,因此替换了自定义指令标记.


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

  • 埃德加:它没有在1.3.0中删除. (17认同)
  • 这令人失望.我发现当你的指令模板是transcluding时,replace是必不可少的,并且包含了像ul | ol/li这样的依赖于层次结构的依赖元素.我使用replace来确保构造像菜单和诸如ul/li之类的东西的指令的标记最终得到实际工作的标记.我真的希望WebComponents(我没有多少研究)有另一种解决这个问题的方法 (10认同)
  • 最后的评论给我们带来了好消息,替换不会被删除:) (2认同)

Mar*_*kos 20

如果您担心replace: true将在下一版本中删除,则可以使用postCompile函数来复制行为.

/// 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);
            };
        }
    }; 
});
Run Code Online (Sandbox Code Playgroud)

  • @ Ali.MD有些情况下你想要装饰(读取:添加功能)某个元素但是将它包装在另一个div中会导致麻烦.如果你想使用多个装饰器,html结构将会发生巨大变化,因此你可能会破坏css或javascript. (10认同)

geo*_*awg 6

来自GitHub:

Caitp--它已被弃用,因为已知的,非常愚蠢的问题replace: true,其中一些问题无法以合理的方式得到解决.如果你小心并避免这些问题,那么对你有更多的权力,但为了新用户的利益,更容易告诉他们"这会让你头疼,不要这样做".

- AngularJS问题#7636

replace:true 已弃用

来自Docs:

replace ([DEPRECATED!],​​将在下一个主要版本中删除 - 即v2.0)

指定模板应替换的内容.默认为false.

  • true - 模板将替换指令的元素.
  • false - 模板将替换指令元素的内容.

- AngularJS综合指令API


Bas*_*ter 5

我想说它已被删除是一件好事,因为它可以防止您将指令(组件)的内部工作暴露给外部世界。将您的模板视为影子 DOM,并将您的指令与普通 HTML 元素(如按钮)进行比较。当您悬停或单击它们时,您不会看到所有类型的类被添加和样式应用于这些元素。这一切都“隐藏”在里面。因为目前对 shadow DOM 的支持有些有限,所以它是一种变通方法,但它已经使您能够成为未来的证明。

  • 编码表单的方式和需要替换的 SVG 元素存在问题。但是,我同意,调试起来更难。 (2认同)