Jakie jest znaczenie wymagania: „ngModel”?

92

To jest kod HTML mojej dyrektywy:

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

W mojej dyrektywie mam to:

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

Czy ktoś może mi powiedzieć, jakie jest znaczenie wymagania: „ngModel”? Widzę to w wielu różnych dyrektywach. Czy mogę nazwać to modalnym?

Jestem zdezorientowany, ponieważ kiedy zmieniam go na modalny danych, otrzymuję wiadomość od Angulara

Controller 'ngModel', required by directive 'textarea', can't be found!
krusty.ar
źródło
Gdziekolwiek używasz tej dyrektywy, powinien istnieć atrybut zdefiniowany jakong-model='property'
Chandermani
3
Czy zamiast tego mogę mieć model danych? Dlaczego czasami widzę: „require: '? NgModel',„ To zagmatwane.

Odpowiedzi:

117

requireInstrukcja daje sterownik do dyrektywy to nazwę jako czwarty argument do swojej linkfunkcji. (Możesz użyć ^do wyszukania kontrolera w elemencie nadrzędnym; ?sprawia , że jest opcjonalny.) Więc require: 'ngModel'daje ci kontroler dla ngModeldyrektywy, którym jest plikngModelController .

Kontrolery dyrektywy można napisać w celu zapewnienia interfejsów API, z których mogą korzystać inne dyrektywy; z ngModelController, uzyskujesz dostęp do specjalnych wbudowanych funkcji, w ngModeltym do pobierania i ustawiania wartości. Rozważmy następujący przykład:

<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();                
      };
    }
  }
});

Ta dyrektywa używa ngModelkontrolera do pobierania i ustawiania wartości koloru z próbnika kolorów. Zobacz ten przykład JSFiddle: http://jsfiddle.net/BinaryMuse/AnMhx/

Jeśli używasz require: 'ngModel', prawdopodobnie nie powinieneś także używać ngModel: '='w swoim zakresie izolowanym; ngModelControllerdaje cały dostęp trzeba zmienić wartość.

Dolny przykład na stronie domowej AngularJS również wykorzystuje tę funkcjonalność (z wyjątkiem używania niestandardowego kontrolera, nie ngModel).


Jeśli chodzi o wielkość liter dyrektywy, na przykład ngModelvs ng-modelvs data-ng-model: podczas gdy Angular obsługuje używanie wielu formularzy w DOM, to kiedy odwołujesz się do dyrektywy po nazwie (na przykład podczas tworzenia dyrektywy lub używania require), zawsze używasz lowerCamelCase forma nazwy.

Michelle Tilley
źródło
2
Czy jest jakiś szczególny powód, dla którego require: 'ngModel'należy go używać ngModel: '='?
ErikAGriffin
33

Zgodnie z dokumentacją dotyczącą tworzenia dyrektyw niestandardowych : (Najpierw pytanie w komentarzu)

Czy mogę data-ng-modelzamiast tego dostać ?

Odpowiedź:

Najlepsza praktyka : preferuj format rozdzielany myślnikami (np. ng-bindDla ngBind). Jeśli chcesz użyć narzędzia do walidacji HTML, możesz zamiast tego użyć datawersji z prefiksem (np. data-ng-bindDla ngBind). Inne formularze przedstawione powyżej są akceptowane ze względu na przestarzałe, ale radzimy ich unikać.

Przykłady:

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

Po drugie, co ?ngModelreprezentuje?

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

Podczas korzystania z dyrektywy wymusza użycie jej wraz z atrybutem / kontrolerem ng-model.

requireustawienie

(Wyciąg z książki AngularJS autorstwa Brada Greena i Shyama Seshadri)

Inne dyrektywy mogą to mieć kontroler przekazany do nich z wymaganą składnią właściwości . Pełna forma wymagania wygląda następująco:

require: '^?directiveName'

Opcje:

  1. directiveName

    Ta nazwa w kształcie wielbłąda określa, z której dyrektywy powinien pochodzić kontroler. Więc jeśli nasza <my-menuitem>dyrektywa musi znaleźć kontrolera w swoim rodzicu<my-menu> , napiszemy go jako myMenu.

  2. ^

    Domyślnie Angular pobiera kontroler z nazwanej dyrektywy w tym samym elemencie. Dodanie tego opcjonalnego ^symbolu nakazuje również podejść po drzewie DOM w celu znalezienia dyrektywy. Na przykład musielibyśmy dodać ten symbol; końcowy ciąg byłby^myMenu .

  3. ?

    Jeśli wymagany kontroler nie zostanie znaleziony, Angular zgłosi wyjątek, aby poinformować Cię o problemie. Dodanie ?symbolu do ciągu mówi, że ten kontroler jest opcjonalny i nie należy zgłaszać wyjątku, jeśli nie zostanie znaleziony. Choć wydaje się to mało prawdopodobne, gdybyśmy chcieli, abyśmy <my-menu-item>używali go bez <mymenu>kontenera, moglibyśmy dodać to jako ostateczny ciąg wymagań ?^myMenu.

Radim Köhler
źródło
21

require:'ngModel'I require:'^ngModel'pozwalają wstrzyknąć modelu dołączony do elementu lub jego elementu nadrzędnego, w którym dyrektywa jest związany.

Jest to w zasadzie najłatwiejszy sposób na przekazanie ngModel do funkcji link / kompilacji zamiast przekazywania go za pomocą opcji zakresu. Po uzyskaniu dostępu do ngModel możesz zmienić jego wartość za pomocą $setViewValue, zabrudzić / wyczyścić za pomocą$formatters , zastosować obserwatory itp.

Poniżej znajduje się prosty przykład przekazania ngModel i zmiany jego wartości po 5 sekundach.

Demo: 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);                
        };
    }
  };
});
codef0rmer
źródło