[Javascript] Why is `replace` property deprecated in AngularJS directives?


Answers

If you fear that replace: true will be removed in next version, you can use a postCompile function to replicate the behavior.

/// 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);
            };
        }
    }; 
});
Question

According to the API docs, directives' replace attribute is deprecated, so in the future, all directives will behave with the current default of replace: false.

This removes developers' ability to replace an element directive's element, with no apparent replacement for this functionality.

See this plunk for an example of how element directives work with and without replace: true.

Why is this useful attribute being deprecated with no replacement?




I'd say it's a good thing that is has been removed because it prevents you from exposing inner workings of a directive (component) to the outside world. Look at your template as being a shadow DOM and compare your directive with normal HTML elements like a button You don't see all kinds of classes being added and styling being applied to those elements either when you hover or click them. It's all 'hidden' inside. Because support for shadow DOM is somewhat limited at the moment it is kind of a workaround but it already enables you to be future proof.