Имя директивы и имя атрибута конфликтуют

Я столкнулся с проблемой конфликтующих директив и имен атрибутов. Это упрощенная версия моей проблемы: есть две директивы, где имя первой директивы является именем атрибута второй директивы:

angular.module('mymodule').directive('property', function() {
    return {
        template: '<div>Property Directive</div>'
    };
});

angular.module('mymodule').directive('fail', function() {
    return {
        scope: {
            property: '='
        },
        template: '<div>{{property}}</div>'
    }
});

Когда я пытаюсь добавить свою вторую директиву в HTML-файл:

<fail property="'test'"></fail>

Я получаю следующую ошибку:

Error: [$compile:multidir] Multiple directives [fail, property] asking for template on: <fail property="'test'">http://errors.angularjs.org/1.3.0-rc.4/$compile/multidir?p0=fail&p1=property&p2=template&p3=%3Cfail%20property%3D%22'test'%22%3E

Теперь, это не было бы проблемой, если бы обе директивы были в моих модулях, поскольку переименовать их было бы легко. Но у меня есть конфликтующие имена директив / атрибутов из разных внешних модулей, которые я использую в своем приложении.

Как я могу сказать угловой, что атрибут property не является директивой в данном конкретном случае?

1 ответ

Решение

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

  • $compileProvider

    • Чтобы зарегистрировать новую директиву, переопределив конструктор угловой директивы app.directive,
  • $provide service

    • Чтобы украсить директиву плохим именем, получите ее определение и верните просто пустую фабрику без операций.
    • Вы можете украсить директиву postFixing с помощью Directive ключевое слово. Они также зарегистрированы как фабрика.

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

app.config(['$compileProvider', function ($compileProvider) {
    //Override directive constructor
    app.directive = function (name, dirObject) {
        //Register a directive
        $compileProvider.directive(name, function() {
           return dirObject[0];
        });
    };
}]).config(['$provide', function($provide){
    //Decorate target directive
    $provide.decorator('propertyDirective', ['$delegate', function($delegate){
        //Just register a new directive with source's definition
        app.directive('cmProperty', $delegate);
        //return a no operation factory as directive constructor, to make it inactive
        return function() { return angular.noop };
    }]);
}]);

демонстрация

Вы можете автоматизировать это, поместив имена целевых директив в константу и запустив цикл декораторов для автоматического префикса / переименования (воссоздания с другим именем).


Обновить

Смотрите общее решение в моем хранилище

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