Qual è il significato di require: 'ngModel'?


92

Questo è l'HTML per la mia direttiva:

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

Nella mia direttiva ho questo:

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

Qualcuno può dirmi qual è il significato di require: 'ngModel'? Lo vedo in molte direttive diverse. Potrei chiamare questo data-modale?

Sono confuso perché quando lo cambio in data-modal ricevo un messaggio da Angular dicendo

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

Ovunque si utilizzi questa direttiva dovrebbe esserci un attributo definito comeng-model='property'
Chandermani

3
Posso invece avere un modello data-ng? Inoltre, perché a volte vedo: "require: '? NgModel'," è fonte di confusione.

Risposte:


117

L' requireistruzione ti fornisce il controller per la direttiva che chiami come quarto argomento della tua linkfunzione. (Puoi usare ^per cercare il controller su un elemento genitore; lo ?rende opzionale.) Quindi require: 'ngModel'ti dà il controller per la ngModeldirettiva, che è un filengModelController .

È possibile scrivere controller di direttiva per fornire API utilizzabili da altre direttive; con ngModelController, hai accesso a funzionalità speciali incorporate ngModel, inclusa l'acquisizione e l'impostazione del valore. Considera il seguente esempio:

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

Questa direttiva utilizza il ngModelcontroller per ottenere e impostare il valore del colore dal colorpicker. Guarda questo esempio JSFiddle: http://jsfiddle.net/BinaryMuse/AnMhx/

Se stai usando require: 'ngModel', probabilmente non dovrebbe anche utilizzare ngModel: '='nel vostro campo di applicazione isolare; la ngModelControllersi dà tutto l'accesso è necessario modificare il valore.

Anche l'esempio in basso sulla homepage di AngularJS utilizza questa funzionalità (tranne che per l'utilizzo di un controller personalizzato, non ngModel).


Per quanto riguarda l'involucro di una direttiva, ad esempio, ngModelvs ng-modelvs data-ng-model: mentre Angular supporta l'utilizzo di più moduli sul DOM, quando si fa riferimento a una direttiva per nome (ad esempio, quando si crea una direttiva o si utilizza require), si utilizza sempre lowerCamelCase forma del nome.


2
C'è un motivo particolare per cui require: 'ngModel'dovrebbe essere usato ngModel: '='?
ErikAGriffin

33

Come indicato nella documentazione sulla creazione di direttive personalizzate : (in primo luogo alla tua domanda nel commento)

Posso averne uno data-ng-modelinvece?

La risposta:

Best practice : preferisci utilizzare il formato delimitato da trattini (ad esempio ng-bindper ngBind). Se vuoi usare uno strumento di convalida HTML, puoi invece usare la dataversione -prefixed (ad esempio data-ng-bindper ngBind). Gli altri moduli sopra indicati sono accettati per motivi precedenti, ma ti consigliamo di evitarli.

Esempi:

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

In secondo luogo, cosa ?ngModelrappresenta?

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

Quando si utilizza la propria direttiva, la forza viene utilizzata insieme all'attributo / controller ng-model.

L' requireimpostazione

(Estratto dal libro AngularJS di Brad Green e Shyam Seshadri)

Questo controller può essere passato ad altre direttive con la sintassi della proprietà require . La forma completa di require si presenta come:

require: '^?directiveName'

Opzioni:

  1. directiveName

    Questo nome a forma di cammello specifica da quale direttiva dovrebbe provenire il controller. Quindi, se la nostra <my-menuitem>direttiva ha bisogno di trovare un controller sul suo genitore <my-menu>, lo scriveremo come myMenu.

  2. ^

    Per impostazione predefinita, Angular ottiene il controller dalla direttiva denominata sullo stesso elemento. L'aggiunta di questo ^simbolo opzionale dice di salire anche sull'albero DOM per trovare la direttiva. Per l'esempio, avremmo bisogno di aggiungere questo simbolo; la stringa finale sarebbe ^myMenu.

  3. ?

    Se il controller richiesto non viene trovato, Angular lancerà un'eccezione per informarti del problema. L'aggiunta di un ?simbolo alla stringa indica che questo controller è facoltativo e che un'eccezione non dovrebbe essere generata se non viene trovata. Anche se sembra improbabile, se volessimo usarli <my-menu-item>senza un <mymenu>contenitore, potremmo aggiungerlo per una stringa di richiesta finale di ?^myMenu.


21

L' require:'ngModel'e require:'^ngModel'permettono di iniettare il modello allegato al elemento o suo elemento genitore in cui la direttiva è destinata a.

È fondamentalmente un modo più semplice per passare ngModel nella funzione link / compile invece passarlo usando un'opzione di ambito. Una volta che hai accesso a ngModel, puoi cambiarne il valore usando $setViewValue, renderlo sporco / pulito usando $formatters, applicare watcher, ecc.

Di seguito è riportato un semplice esempio per passare ngModel e modificarne il valore dopo 5 secondi.

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);                
        };
    }
  };
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.