Was bedeutet erfordern: 'ngModel'?

92

Dies ist der HTML-Code für meine Direktive:

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

In meiner Richtlinie habe ich Folgendes:

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

Kann mir jemand sagen, welche Bedeutung die Anforderung hat: 'ngModel'? Ich sehe das in vielen verschiedenen Richtlinien. Könnte ich das datenmodal nennen?

Ich bin verwirrt, denn wenn ich es auf datenmodal ändere, erhalte ich eine Nachricht von Angular

Controller 'ngModel', required by directive 'textarea', can't be found!
krusty.ar
quelle
Wo immer Sie diese Direktive verwenden, sollte ein Attribut definiert sein alsng-model='property'
Chandermani
3
Kann ich stattdessen ein Datenmodell haben? Auch warum sehe ich manchmal: "erfordern: '? NgModel'," Es ist verwirrend.

Antworten:

117

Die requireAnweisung gibt Ihnen den Controller für die Direktive, die Sie als viertes Argument für Ihre linkFunktion benennen . (Sie können verwenden ^, um nach dem Controller in einem übergeordneten Element zu suchen. Dies ?ist optional.) require: 'ngModel'Sie erhalten also den Controller für die ngModelDirektive, bei der es sich um eine handeltngModelController .

Direktiven-Controller können so geschrieben werden, dass sie APIs bereitstellen, die andere Direktiven verwenden können. Mit erhalten ngModelControllerSie Zugriff auf spezielle Funktionen, die integriert sind ngModel, einschließlich Abrufen und Festlegen des Werts. Betrachten Sie das folgende Beispiel:

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

Diese Anweisung verwendet den ngModelController, um den Wert der Farbe vom Farbpicker abzurufen und einzustellen. Siehe dieses JSFiddle-Beispiel: http://jsfiddle.net/BinaryMuse/AnMhx/

Wenn Sie verwenden require: 'ngModel', sollten Sie wahrscheinlich nicht auch verwenden werden ngModel: '='in Ihrem Isolat Umfang; Das ngModelControllergibt Ihnen allen Zugriff, den Sie benötigen, um den Wert zu ändern.

Das untere Beispiel auf der AngularJS-Homepage verwendet diese Funktionalität ebenfalls (außer bei Verwendung eines benutzerdefinierten Controllers, nicht ngModel).


Was das Gehäuse einer Direktive betrifft, z. B. ngModelvs ng-modelvs data-ng-model: Während Angular die Verwendung mehrerer Formulare im DOM unterstützt require, verwenden Sie immer den LowerCamelCase , wenn Sie namentlich auf eine Direktive verweisen (z. B. beim Erstellen einer Direktive oder beim Verwenden einer Direktive ) Form des Namens.

Michelle Tilley
quelle
2
Gibt es einen bestimmten Grund, warum require: 'ngModel'verwendet werden sollte ngModel: '='?
ErikAGriffin
33

Wie in der Dokumentation zum Erstellen benutzerdefinierter Richtlinien angegeben : (Zunächst zu Ihrer Frage im Kommentar)

Kann ich data-ng-modelstattdessen eine haben?

Die Antwort:

Best Practice : Verwenden Sie lieber das durch Bindestriche getrennte Format (z . B. ng-bindfür ngBind). Wenn Sie ein HTML-Validierungswerkzeug verwenden möchten, können Sie stattdessen die datavorfixierte Version (z . B. data-ng-bindfür ngBind) verwenden. Die anderen oben gezeigten Formulare werden aus früheren Gründen akzeptiert. Wir empfehlen Ihnen jedoch, sie zu vermeiden.

Beispiele:

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

Zweitens, was ?ngModelrepräsentiert das?

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

Wenn Sie Ihre Direktive verwenden, wird die Verwendung zusammen mit dem Attribut / Controller erzwungen ng-model.

Die requireEinstellung

(Auszug aus dem Buch AngularJS von Brad Green & Shyam Seshadri)

Bei anderen Anweisungen kann dieser Controller mit der erforderlichen Eigenschaftssyntax an sie übergeben werden . Die vollständige Form der Anforderung sieht aus wie:

require: '^?directiveName'

Optionen:

  1. directiveName

    Dieser Name in Kamelhülle gibt an, von welcher Direktive der Controller stammen soll. Wenn unsere <my-menuitem>Direktive also einen Controller auf ihrem übergeordneten <my-menu>Element finden muss, schreiben wir ihn als myMenu.

  2. ^

    Standardmäßig ruft Angular den Controller von der genannten Direktive für dasselbe Element ab. Wenn Sie dieses optionale ^Symbol hinzufügen, müssen Sie auch den DOM-Baum nach oben gehen, um die Direktive zu finden. Für das Beispiel müssten wir dieses Symbol hinzufügen. Die letzte Zeichenfolge wäre ^myMenu.

  3. ?

    Wenn der erforderliche Controller nicht gefunden wird, löst Angular eine Ausnahme aus, um Sie über das Problem zu informieren. Das Hinzufügen eines ?Symbols zur Zeichenfolge besagt, dass dieser Controller optional ist und dass keine Ausnahme ausgelöst werden sollte, wenn sie nicht gefunden wird. Obwohl es unwahrscheinlich klingt, wenn wir <my-menu-item>s ohne <mymenu>Container verwenden möchten, könnten wir dies für eine letzte erforderliche Zeichenfolge von hinzufügen ?^myMenu.

Radim Köhler
quelle
20

Mit require:'ngModel'und require:'^ngModel'können Sie das Modell einfügen, das an das Element oder dessen übergeordnetes Element angehängt ist, an das die Direktive gebunden ist.

Dies ist im Grunde die einfachste Möglichkeit, ngModel an die Link / Compile-Funktion zu übergeben, anstatt es mit einer Bereichsoption zu übergeben. Sobald Sie Zugriff auf ngModel haben, können Sie seinen Wert mit ändern $setViewValue, ihn schmutzig / sauber machen $formatters, Beobachter anwenden usw.

Unten finden Sie ein einfaches Beispiel, um ngModel zu übergeben und seinen Wert nach 5 Sekunden zu ändern.

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
quelle