2013-10-10 6 views
2

Для моего проекта я в настоящее время разрабатываю специальную директиву формы/ввода.Угловая: добавление директивы атрибута по директиве Element

Для меня, например, следующую директиву:

angular.module('myApp').directive("textField", function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     templateUrl : "/common/tpl/form/text-field.html", 
     scope : { 
      label : "@", 
      model : "=" 
     } 
    }; 
}); 

с соответствующим шаблоном:

<div class="form-group"> 
    <label for="{{fieldId}}" class="col-lg-2 control-label">{{label |translate}}</label> 
    <div class="col-lg-10"> 
     <input type="text" class="form-control" id="{{fieldId}}" ng-model="model" placeholder="{{label|translate}}"> 
    </div> 
</div> 

У меня есть много больше пользовательских полей (дата, выберите, дважды выберите, и так далее. ..)

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

<text-field label="app.myLabel" model="myObj.myAttribute"></text-field> 

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

Теперь проблема:

Теперь мне нужно добавить пользовательскую проверку моих моделей входных данных.

я наивный подход, который должен был создать директиву проверки:

directive('myValidation', function(){ 
    return { 
     require: 'ngModel', 
     link: function(scope, elem, attr, ngModel) { 
      ngModel.$parsers.unshift(function (value) { 
       // do some validation 
       return value; 
      }); 
     } 
    }; 
}); 

, а затем использовать его как это:

<text-field label="app.myLabel" model="myObj.myAttribute" myValidation="validationOptions"></text-field> 

Но, конечно, это не работает, просто потому, что текст директива -field, которая заменяет = true, «стирает» директиву проверки на свой элемент.

Может ли кто-нибудь сказать, какой правильный подход должен выполнять директива «пользовательский ввод с презентацией», позволяя утверждать, что часть валидации объявлена ​​в директиве (здесь текстовое поле) и используется на вводе директивы?

Например, есть ли способ сказать: «атрибуты моей директивы элемента будут« скопированы »внутри моей директивы?»

ака:

<text-field label="app.myLabel" model="myObj.myAttribute" **myValidation="validationOptions"**></text-field> 

бы привести:

<div class="form-group"> 
     <label for="{{fieldId}}" class="col-lg-2 control-label">{{label |translate}}</label> 
     <div class="col-lg-10"> 
      <input type="text" class="form-control" id="{{fieldId}}" ng-model="model" **myValidation="validationOptions"** placeholder="{{label|translate}}"> 
     </div> 
    </div> 

Или я просто что-то отсутствует?

Я хотел бы избежать использования включения, чтобы решить эту проблему, потому что это обяжет шаблон формы выглядеть следующим образом:

<field label="myLabel"> 
    <input type="text" class="form-control" id="{{fieldId}}" ng-model="model" placeholder= {{label|translate}}">  
</field> 

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

Возможно, трюк может быть выполнен в функции прямой передачи (или post?), Где я бы скопировал атрибуты/директивы из тега текстового поля в свой тег child (input)?

Может ли кто-нибудь просто зажечь туда путь?

ответ

3

Не могли бы вы попробовать это:

  • Написать validate директиву. Это будет иметь контроллер, который предоставляет методы addValidationFunction(fn) и getValidationFunction().

  • Имейте myValidation директивы требует контроллера validate и вызвать ctrl.addValidationFunction(myValidationImplementation) где myValidationImplementation функция реализует логику проверки для этой конкретной директивы.

  • Напишите еще одну директиву, validateInner. Для этого потребуется опционально контроллер validate от его родителя. Эта директива также потребует контроллер ngModel. Если он находит контроллер validate, он вызывает ctrl.getValidationFunction() и регистрирует функцию с ngModel т.е.:

    require: ["^?validate", "ngModel"], 
    link: function(scope,el,attrs,ctrls) { 
        if(ctrls[0] != null) { 
         var validationFn = ctrls[0].getValidationFunction(); 
         // register validationFn with ngModel = ctrls[1] 
        } 
        ... 
    } 
    
  • В шаблоне вашего textField:

    <input validate-inner type="text" class="form-control" id="{{fieldId}}" ng-model="model" placeholder="{{label|translate}}"> 
    

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

<text-field label="app.myLabel" model="myObj.myAttribute" 
    validate my-validation="validationOptions"></text-field> 

ПРИМЕЧАНИЕ 1: Я не уверен, что директива replace:true вытирает другие директивы. Если это так, это не последовательное поведение.

Примечание 2: директива myValidation получает называется <xxx my-validation> (примечание верблюжьего → тира случай). Если ваш код выше не опечатка, то вот почему <text-field> кажется, протирает myValidation.

+0

Я галлюцинировал, заменил: правда не вытирает другие директивы, проблема с camelCase - это все, что было. Но вы правы, это тот подход, который я, наконец, должен был сделать, спасибо –

Смежные вопросы