2015-03-26 1 views
1

Мне нужно создать директиву myDirective который считывает все ключи нг-сообщения в нем, и он по-прежнему создает действительные нг-сообщения элемента:Извлечь ключ нг-сообщение от нг-сообщений

шаблон Директивы:

<div id="myDirective"> 
    <div ng-messages="myform.$error" ng-transclude></div> 
</div> 

Использование:

<my-directive> 
    <div ng-message="required">something is required</div> 
    <div ng-message="custom">custom validation</div> 
</my-directive> 

Так что в этом случае я хотел бы получить массив «необходимый» и «обычай». Проблема в том, что я не могу этого сделать, поскольку все элементы ng-messsage уже скрыты (удалены из DOM, чтобы быть более точными) к моменту, когда моя директива попадает в свою собственную функцию связывания. Как обойти это?

ответ

2

Содержимое директивы удаляется во время фазы компиляции, потому что ваша директива имеет transclude: true (я предполагаю, что вы используете ng-transclude).

В этом случае содержимое доступно через переданную функцию transclude (это фактически то, что ng-transclude использует под обложками).

transclude функция является пятым параметром функции link (или предварительно ссылки):

link: function(scope, element, attrs, ctrls, transclude){ 
    var transcludedContents; // jqLite of the contents 

    transclude(function(clone){ 
    transcludedContents = clone; 
    }); 

    // do whatever you do to extract ng-message values from transcludedContents 
    // just remember, that it could also come in the form: 
    // <ng-message when="required"> and 
    // <div ng-message-exp="errorMessage.type"> 
} 

Возможно ленивее среди нас не хотел бы иметь дело с DOM подсчетом, и, таким образом Вы можете создать еще один обработчик для ng-message, который взаимодействует с вашим my-directive, чтобы зарегистрировать себя:

.directive("myDirective", function() { 
    return { 
    transclude: true, 
    templateUrl: "myDirective.template.html", 
    controller: function() { 
     var messages = []; 
     this.registerNgMessage = function(val) { 
     messages.push(val); 
     }; 
    } 
    }; 
}) 
.directive("ngMessage", complementaryNgMessageDirective) 
.directive("ngMessageExp", complementaryNgMessageDirective); 

function complementaryNgMessageDirective() { 
    return { 
    priority: 10, // must be higher than ngMessage, because ngMessage is terminal 
    require: "^?myDirective", // must be optional not to break existing code 
    link: function(scope, element, attrs, myDirectiveCtrl) { 

     if (!myDirectiveCtrl) return; // do nothing, if not paired with myDirective 

     var staticExp = attrs.ngMessage || attrs.when; 
     var dynamicExp = attrs.ngMessageExp || attrs.whenExp; 

     var val; 
     if (dynamicExp) { 
     val = scope.$eval(dynamicExp); 
     } else { 
     val = staticExp; 
     } 

     myDirectiveCtrl.registerNgMessage(val); 
    } 
    }; 
}