Почему свойство "replace" устарело в директивах AngularJS?

В соответствии с API docs атрибут директивы replace устарел, поэтому в будущем все директивы будут вести себя с текущим значением по умолчанию replace: false.

Это устраняет способность разработчиков заменять элемент директивы элемента, без видимой замены для этой функции.

См. эту панель для примера того, как директивы элемента работают с и без replace: true.

Почему этот полезный атрибут устарел без замены?

Ответ 1

UPDATE

Один из сотрудников сказал, что он не будет удален, но известные ошибки не будут исправлены. https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb#commitcomment-8124407

ОРИГИНАЛ

Вот фиксация этого изменения: https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb

Флаг replace для определения директив, которые заменяют элемент что они будут включены, будут удалены в следующей крупной версии angular. Эта функция имеет сложную семантику (например, как объединяются атрибуты) и приводит к большему количеству проблем по сравнению с тем, что он решает. Кроме того, с WebComponents нормально иметь пользовательские элементы в DOM.

Мне кажется, что это сочетание сложности и преимуществ поддержки.

И, по-видимому, одна причина, по которой разработчик использовал его, потому что они предпочли семантически правильную разметку для инъекции, заменив тем самым настраиваемый тег директивы.


Прочитайте комментарии ниже по этой ссылке, и, по-видимому, многие люди хотят, чтобы она осталась.

Ответ 2

Если вы боитесь, что в следующей версии будет удален replace: true, вы можете использовать функцию postCompile для репликации поведения.

/// Replace element with it 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);
            };
        }
    }; 
});

Ответ 3

Из GitHub:

Caitp-- Это устарело, потому что существуют известные, очень глупые проблемы с replace: true, некоторые из которых не могут быть исправлены разумным образом. Если вы будете осторожны и избежите этих проблем, это даст вам больше энергии, но в интересах новых пользователей легче просто сказать им: "это даст вам головную боль, не делайте этого".

- AngularJS Issue # 7636

 replace:true устарела

Из документов:

replace ([DEPRECATED!], will be removed in next major release - т.е. v2.0)

укажите, что шаблон должен заменить. По умолчанию false.

  • true - шаблон заменит элемент директивы.
  • false - шаблон заменит содержимое элемента директивы.

- API всеобъемлющей директивы AngularJS

См. также - Как использовать & # 39; replace & # 39; особенность для пользовательских директив AngularJS?

Ответ 4

Я бы сказал, что это хорошая вещь, которая была удалена, потому что она мешает вам разоблачить внутреннюю работу директивы (компонента) во внешнем мире. Посмотрите на свой шаблон как теневой DOM и сравните свою директиву с обычными элементами HTML, как кнопка. Вы не видите добавление всех видов классов и стилей, применяемых к этим элементам, когда вы наводите или нажимаете на них. Все это "скрыто" внутри. Поскольку поддержка теневого DOM несколько ограничена на данный момент, это своего рода обходной путь, но он уже позволяет вам быть будущим доказательством.