¿Cuál es el significado de require: ‘ngModel’?

Este es el HTML de mi directiva:

 

En mi directiva tengo esto:

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

¿Puede alguien decirme cuál es la importancia de require: ‘ngModel’? Veo esto en muchas directivas diferentes. ¿Podría llamar a esto datos-modal?

Estoy confundido porque cuando lo cambio a datos-modal me sale un mensaje de Angular diciendo

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

La instrucción require le proporciona el controlador para la directiva que usted nombra como el cuarto argumento para su función de link . (Puede usar ^ para buscar el controlador en un elemento primario require: 'ngModel' hace opcional.) Por lo tanto, require: 'ngModel' le proporciona el controlador para la directiva ngModel , que es un ngModelController .

Los controladores de directivas pueden escribirse para proporcionar API que otras directivas pueden usar; con ngModelController , obtiene acceso a la funcionalidad especial que está incorporada en ngModel , que incluye obtener y establecer el valor. Considere el siguiente ejemplo:

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

Esta directiva utiliza el controlador ngModel para obtener y establecer el valor del color del colorpicker. Vea este ejemplo de JSFiddle: http://jsfiddle.net/BinaryMuse/AnMhx/

Si está usando require: 'ngModel' , probablemente no debería estar usando ngModel: '=' en su scope aislado; ngModelController le brinda todo el acceso que necesita para cambiar el valor.

El ejemplo inferior en la página de inicio de AngularJS también usa esta funcionalidad (excepto que usa un controlador personalizado, no ngModel ).


En cuanto a la carcasa de una directiva, por ejemplo, ngModel vs ng-model vs data-ng-model : mientras Angular admite el uso de múltiples formularios en el DOM, cuando se refiere a una directiva por nombre (por ejemplo, cuando se crea una directiva, o using require ), siempre usa la forma del nombre deCamelCase inferior.

Como se indica en la documentación Creación de directivas personalizadas : (En primer lugar a su pregunta en el comentario)

¿Puedo tener un data-ng-model lugar?

La respuesta:

Mejores prácticas : Prefiera usar el formato delimitado por guiones (p. Ej., ng-bind para ngBind ). Si desea utilizar una herramienta de validación de HTML, puede utilizar la versión de data prefijada (por ejemplo, data-ng-bind para ngBind ). Los otros formularios que se muestran arriba son aceptados por razones heredadas, pero le recomendamos que los evite.

Ejemplos:

     

En segundo lugar, ¿ ?ngModel representa el ?ngModel ?

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

Cuando usa su directiva, la obliga a usarla junto con el atributo / controlador ng-model .

La configuración de require

(Extracto del libro AngularJS de Brad Green y Shyam Seshadri)

Otras directivas pueden tener este controlador que se les pasa con la syntax de propiedad require . La forma completa de require se ve así:

 require: '^?directiveName' 

Opciones:

  1. directiveName

    Este nombre de camel-cased especifica de qué directiva debería venir el controlador. Entonces, si nuestra directiva necesita encontrar un controlador en su padre , lo escribiríamos como myMenu.

  2. ^

    Por defecto, Angular obtiene el controlador de la directiva nombrada en el mismo elemento. Agregar este símbolo opcional ^ indica que también debe subir el árbol DOM para encontrar la directiva. Por ejemplo, necesitaríamos agregar este símbolo; la última cuerda sería ^myMenu .

  3. ?

    Si no se encuentra el controlador requerido, Angular lanzará una excepción para informarle sobre el problema. Agregar un ? El símbolo de la cadena dice que este controlador es opcional y que no se debe lanzar una excepción si no se encuentra. Aunque suena poco probable, si quisiéramos que s se usara sin un contenedor , podríamos agregar esto para una cadena de requerimiento final de ?^myMenu .

Los require:'ngModel' y require:'^ngModel' permiten inyectar el modelo adjunto al elemento o su elemento primario al que está sujeta la directiva.

Básicamente es la forma más fácil de pasar ngModel a la función de enlace / comstackción en lugar de pasarlo utilizando una opción de ámbito. Una vez que tenga acceso a ngModel, puede cambiar su valor usando $setViewValue , hacerlo sucio / limpio usando $formatters , aplicar vigilantes, etc.

A continuación se muestra un ejemplo simple para pasar ngModel y cambiar su valor después de 5 segundos.

Demostración: 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); }; } }; });