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

时间:2014-06-12 22:37:28

标签: javascript angularjs angularjs-directive

根据the API docs,指令'replace属性已弃用,因此将来所有指令的行为都将使用当前默认值replace: false

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

有关元素指令如何与replace: true一起使用的示例,请参阅this plunk

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

4 个答案:

答案 0 :(得分:70)

<强>更新

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

<强> ORIGINAL

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

  

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

在我看来,它是复杂性与利益相结合,以维持支持。

显然开发人员之所以使用它是因为他们首选注入语义正确的标记,因此替换了自定义指令标记。


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

答案 1 :(得分: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);
            };
        }
    }; 
});

答案 2 :(得分:6)

来自GitHub:

  

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

- AngularJS Issue #7636

replace:true已弃用

来自文档:

  

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

     

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

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

- AngularJS Comprehensive Directive API

答案 3 :(得分:4)

我会说这是一件好事,因为它会阻止你将指令(组件)的内部工作暴露给外界。将您的模板视为阴影DOM,并将您的指令与普通HTML元素(如按钮)进行比较您没有看到添加的所有类,并且在您悬停或单击它们时样式应用于这些元素。它全都“隐藏”在里面。因为对shadow DOM的支持在某种程度上是有限的,所以它是一种解决方法,但它已经使你能够成为未来的证明。