2013-07-01 4 views
10

У меня есть элемент ввода, и я хотел бы привязать к нему ngModel и ngClass с помощью настраиваемой директивы, но у меня возникают некоторые проблемы.Добавление ngModel для ввода с директивой

Что у меня есть:

<input type="text" myDirective="PropertyFromScope" /> 

То, что я хочу, как результат:

<input type="text" ng-model="PropertyFromScope" ng-class="{'class' : MethodFromScope}" /> 

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

Вот что я получил до сих пор:

angular.module('customDirectives', []) 
.directive('myDirective', function() { 
    var linker = function (scope, element, attrs) { 
     attrs.$set('ngModel', attrs.myDirective); 
     attrs.$set('ngClass', '{\'class\' : MethodFromScope}'); 
    } 
    return { 
     restrict: 'A',   
     link: linker 
    } 
}); 

Вот JSFiddle: http://jsfiddle.net/Q8QJJ/

+0

доброжелательно поделитесь своим директивным кодом –

+0

Добавлено, но пока не повезло. –

ответ

12

Вы пытаетесь это сделать?

Довольно простое решение:

myApp.directive('myDirective', function ($compile) { 
    return { 
     restrict: 'A',   
     compile: function(element, attrs) { 
      element.attr('ng-model', attrs.myDirective); 
      element.removeAttr("my-directive"); 
      element.attr('ng-class', '{\'class\' : testFunction()}'); 
      return { 
       pre: function preLink(scope, iElement, iAttrs, controller) { }, 
       post: function postLink(scope, iElement, iAttrs, controller) { 
       $compile(iElement)(scope); 
       } 
      } 
     } 
    } 
}); 

Вот скрипка http://jsfiddle.net/V9e9M/

+0

Да! Я вижу, что сгенерированный html правильный, но привязки не работают. –

+0

@ AndréLourenço вы делаете что-то еще в своей директиве? – Nix

+0

Просто добавил jsfiddle, который показывает, что привязка не работает. –

2

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

myApp.directive('myDirective', function ($compile) { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      var wrappedElement = angular.element(
       '<input type="' + attrs.type + '" ng-model="' 
       + attrs.myDirective + '">'); 
      element.replaceWith(wrappedElement); 
      $compile(wrappedElement)(scope); 
     } 
    } 
}); 

Fiddle

Примечание: Я забыл добавить нг-класс, но я предполагаю, что если нг-модель работает, нг-класс должен работать.

Update:

Вот версия, которая использует функцию компиляции:

myApp.directive('myDirective', function() { 
    return { 
     restrict: 'A', 
     compile: function (tElement, tAttrs) { 
      // for some unknown-to-me reason, the input must 
      // be wrapped in a span or div: 
      var tplElement = angular.element('<span><input></span>'); 
      var inputEl = tplElement.find('input'); 
      inputEl.attr('type', tAttrs.type); 
      inputEl.attr('ng-model', tAttrs.myDirective); 
      tElement.replaceWith(tplElement); 
     } 
    }; 
}); 

Fiddle

0

Я высадился на эту страницу с аналогичной проблемой, связывания ngModel с пользовательской директивы , Вопрос несколько лет, но, может быть, мое решение поможет кому-то другому.

Во-первых, в index.html, я использую свою настраиваемую директиву с некоторыми атрибутами. Обратите внимание на штрих-код в html. Значения атрибутов - это то, что я хочу использовать в директиве.

index.html 

<div> 
    <form name="userInfo"> 
     <my-custom-directive for-model="ctrl.userInput" 
          for-label="Enter User Info" 
          for-other="more info for the directive"> 
     <my-custom-directive> 
    </form> 
</div> 
// check to see the binding. 
{{ ctrl.userInput }} 

Далее в partial.html, я собираюсь установить некоторые значения по умолчанию, чтобы увидеть, когда директива работает должным образом, и когда я вижу по умолчанию.

partial.html 

<div class="form-group"> 
    <label>blankLabel</label> 
    <input type="text" 
      class="form-control" 
      ng-model="modelBlank"> 
</div> 

Директива нуждается в другом синтаксисе, который, вероятно, является наиболее распространенной проблемой. Мне нравится определять переменную, поскольку я, вероятно, назначаю несколько атрибутов. Затем вызовите .attr() в переменной и передайте новую информацию, которую вы хотите применить. В этом случае буквально «ng-model» и значение настраиваемого атрибута, установленного в index.html.

directive.js 

.directive('myCustomDirective', function() { 
    return { 
     templateUrl: 'partial.html', 
     compile: function (element, attributes) { 
      // Find the right element in the partial and assign a variable 
      var inputTag = element.find('input'); 
      // use .attr() on the variable and pass it two arguments. 
      inputTag.attr('ng-model', attributes.forModel); 
      // Find a different element in the partial and replace the text. 
      var labelTag = element.find('label'); 
      labelTag.html(attributes.forLabel); 
     } 
    }; 
}) 

Вы можете использовать консоль.log (element), но он будет генерировать много информации. Лучше осмотреть элемент после загрузки страницы, чтобы увидеть, что модель ng установлена ​​на пользовательское значение. Если он правильно подключен, {{ctrl.userInput}} на странице index.html должен показать текст, введенный в форму.

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

<my-custom-directive for-model="ctrl.userName" 
        for-label="Enter Your Name:" 
        for-other="more info for the directive"> 
<my-custom-directive> 
<my-custom-directive for-model="ctrl.userSelection" 
        for-label="Make a selection:" 
        for-other="more info for the directive"> 
<my-custom-directive> 

Лично я никогда не имел проблем, добавляя атрибуты или угловые директивы с помощью этого метода, в том числе вещи как uib-typeahead. Просто помните о различиях синтаксиса между html и javascript.

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