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

Согласно документации API, директивы replace атрибут устарел, поэтому в будущем все директивы будут работать с текущим значением по умолчанию replace: false,

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

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

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

4 ответа

Решение

ОБНОВИТЬ

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

ОРИГИНАЛ

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

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

Для меня это звучит как сочетание сложности и пользы для поддержки.

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


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

Если вы боитесь этого 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);
            };
        }
    }; 
});

Из GitHub:

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

- AngularJS Issue # 7636

replace:true устарела

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

replace ([УСТАРЕЛО!] Будет удалено в следующем основном выпуске - т.е. v2.0)

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

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

- AngularJS Комплексная Директива API

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

Другие вопросы по тегам