Какое значение требует: "ngModel"?

Это HTML для моей директивы:

<textarea data-modal="modal" data-mydir ng:model="abc"></textarea>

В моей директиве у меня есть следующее:

return {
        require: 'ngModel',
        replace: true,
        scope: {
            modal: '=modal',
            ngModel: '=',
            pid: '=pid'
        },

Может ли кто-нибудь сказать мне, какое значение требуется: "ngModel"? Я вижу это во многих разных директивах. Могу ли я назвать это модально?

Я запутался, потому что, когда я меняю его на data-modal, я получаю сообщение от Angular, говоря

Controller 'ngModel', required by directive 'textarea', can't be found!

Ответ 1

Команда require дает вам контроллер для директивы, которую вы называете четвертым аргументом для вашей функции link. (Вы можете использовать ^ для поиска контроллера на родительском элементе, ? делает его необязательным.) Таким образом, require: 'ngModel' предоставляет вам контроллер для директивы ngModel, который является ngModelController.

Контроллеры директив могут быть написаны для предоставления API, которые могут использовать другие директивы; с ngModelController вы получаете доступ к специальной функциональности, встроенной в ngModel, включая получение и настройку значения. Рассмотрим следующий пример:

<input color-picker ng-model="project.color">
app.directive('colorPicker', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      element.colorPicker({
        // initialize the color to the color on the scope
        pickerDefault: scope.color,
        // update the ngModel whenever we pick a new color
        onColorChange: function(id, newValue) {
          scope.$apply(function() {
            ngModel.$setViewValue(newValue);
          });
        }
      });

      // update the color picker whenever the value on the scope changes
      ngModel.$render = function() {
        element.val(ngModel.$modelValue);
        element.change();                
      };
    }
  }
});

Эта директива использует контроллер ngModel для получения и установки значения цвета из colorpicker. См. Этот пример JSFiddle: http://jsfiddle.net/BinaryMuse/AnMhx/

Если вы используете require: 'ngModel', вы, вероятно, также не должны использовать ngModel: '=' в своей области выделения; ngModelController предоставляет вам весь доступ, необходимый для изменения значения.

В нижнем примере на странице AngularJS также используется эта функция (кроме использования настраиваемого контроллера, а не ngModel).


Как для оболочки директивы, например, ngModel vs ng-model vs data-ng-model: while Angular поддерживает использование нескольких форм в DOM, когда вы ссылаетесь на директиву по имени (например, при создании директивы или использовании require), вы всегда используете форму lowerCamelCase для имени.

Ответ 2

Как указано в Создание пользовательских директив документация: (Во-первых, на ваш вопрос в комментарии)

Можно ли использовать data-ng-model?

Ответ:

Лучшая практика. Предпочитаете использовать формат с разделителями тире (например, ng-bind для ngBind). Если вы хотите использовать инструмент проверки HTML, вы можете вместо этого использовать версию data -prefixed (например, data-ng-bind для ngBind). Другие формы, показанные выше, принимаются по наследственным причинам, но мы советуем вам избегать их.

Примеры:

<my-dir></my-dir>
<span my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span class="my-dir: exp;"></span>

Во-вторых, что означает ?ngModel?

// Always use along with an ng-model
require: '?ngModel',

При использовании вашей директивы он заставляет его использоваться вместе с атрибутом/контроллером ng-model.

Настройка require

(Извлеките из книги AngularJS Брэдом Грин и Шьямом Сешадри)

Другие директивы могут иметь этот контроллер, переданный им с синтаксисом require property. Полная форма запроса выглядит следующим образом:

require: '^?directiveName'

Параметры:

  • directiveName

    Это имя с верблюжьим именем указывает, с какой директивой должен поступать контроллер. Поэтому, если наша директива <my-menuitem> должна найти контроллер на родительском <my-menu>, wed напишите его как myMenu.

  • ^

    По умолчанию Angular получает контроллер от именованной директивы на том же элементе. Добавление этого необязательного символа ^ говорит также о том, чтобы найти дерево DOM, чтобы найти директиву. В качестве примера wed должен добавить этот символ; конечная строка будет ^myMenu.

  • ?

    Если требуемый контроллер не найден, Angular выдаст исключение, чтобы рассказать вам о проблеме. Добавление символа ? в строку говорит о том, что этот контроллер является необязательным и что исключение не должно быть выбрано, если оно не найдено. Хотя это кажется маловероятным, если мы хотим использовать <my-menu-item> без контейнера <mymenu>, мы могли бы добавить это для окончательной строки запроса ?^myMenu.

Ответ 3

require:'ngModel' и require:'^ngModel' позволяют вводить модель, прикрепленную к элементу или его родительскому элементу, к которому привязана директива.

В основном это самый простой способ передать ngModel в функцию link/compile, вместо этого передавая его с помощью опции scope. Когда у вас есть доступ к ngModel, вы можете изменить его значение с помощью $setViewValue, сделать его грязным/чистым, используя $formatters, применить наблюдателей и т.д.

Ниже приведен простой пример, чтобы передать ngModel и изменить его значение через 5 секунд.

Демо: http://jsfiddle.net/t2GAS/2/

myApp.directive('myDirective', function($timeout) {
  return {
    restrict: 'EA',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
        ngModel.$render = function() {
            $timeout(function() {
                ngModel.$setViewValue('StackOverflow');  
            }, 5000);                
        };
    }
  };
});