personalizadas directivas crear compile javascript angularjs templates compilation directive

javascript - crear - directivas angular 6



¿Cuáles son los beneficios de una función de plantilla directiva en Angularjs? (2)

De acuerdo con la documentación, una template puede ser una función que toma dos parámetros, un element y attributes y devuelve un valor de cadena que representa la plantilla. Reemplaza el elemento actual con el contenido del HTML. El proceso de reemplazo migra todos los atributos y clases del antiguo elemento al nuevo.

La función de compile trata de transformar la plantilla DOM. Toma tres parámetros, un element , attributes y función de transclude . El parámetro transclude ha sido desaprobado. Devuelve una función de link .

Parece que una template y una función de compile son muy similares y pueden lograr lo mismo. La función de template define una plantilla y la función de compile modifica la plantilla DOM. Sin embargo, se puede hacer en la función de template sí. No veo por qué modificar la plantilla DOM fuera de la función de template . Y viceversa, si el DOM puede modificarse en la función de compile , ¿cuál es la necesidad de una función de template ?


La función de compilación se puede usar para cambiar el DOM antes de que la función de plantilla resultante esté vinculada al alcance.

Considere el siguiente ejemplo:

<div my-directive></div>

Puede usar la función de compilación para cambiar la plantilla DOM de esta manera:

app.directive(''myDirective'', function(){ return { // Compile function acts on template DOM // This happens before it is bound to the scope, so that is why no scope // is injected compile: function(tElem, tAttrs){ // This will change the markup before it is passed to the link function // and the "another-directive" directive will also be processed by Angular tElem.append(''<div another-directive></div>''); // Link function acts on instance, not on template and is passed the scope // to generate a dynamic view return function(scope, iElem, iAttrs){ // When trying to add the same markup here, Angular will no longer // process the "another-directive" directive since the compilation is // already done and we''re merely linking with the scope here iElem.append(''<div another-directive></div>''); } } } });

De modo que puede usar la función de compile para cambiar la plantilla DOM a lo que quiera si su directiva así lo requiere.

En la mayoría de los casos, tElem e iElem serán el mismo elemento DOM, pero a veces puede ser diferente si una directiva clona la plantilla para eliminar múltiples copias ( ngRepeat ).

Detrás de escena, Angular usa un proceso de representación bidireccional (compilación + enlace) para anular copias de una pieza compilada de DOM, para evitar que Angular tenga que procesar (= analizar las directivas) el mismo DOM una y otra vez para cada instancia en caso de que la directiva selle múltiples clones dando como resultado un rendimiento mucho mejor.

¡Espero que ayude!

AÑADIDO DESPUÉS DEL COMENTARIO:

La diferencia entre una template y la función de compile :

Función de plantilla

{ template: function(tElem, tAttrs){ // Generate string content that will be used by the template // function to replace the innerHTML with or replace the // complete markup with in case of ''replace:true'' return ''string to use as template''; } }

Compile la función

{ compile: function(tElem, tAttrs){ // Manipulate DOM of the element yourself // and return linking function return linkFn(){}; } }

La función de plantilla se invoca antes de llamar a la función de compilación.

Aunque pueden realizar cosas casi idénticas y compartir la misma "firma", la diferencia clave es que el valor de retorno de la función de plantilla reemplazará el contenido de la directiva (o el marcado completo de la directiva si replace: true ), mientras que una función de compilación se espera que cambie el DOM programmatically y devuelva una función de enlace (u objeto con función de enlace pre y post).

En ese sentido, puede pensar en la función de plantilla como una especie de función de conveniencia para no tener que usar la función de compilación si simplemente necesita reemplazar el contenido con un valor de cadena.

¡Espero que ayude!


Uno de los mejores usos de la función de plantilla es generar condicionalmente una plantilla. Esto le permite automatizar la creación de una plantilla basada en un atributo.

He visto algunas plantillas muy grandes que usan ng-if para ocultar secciones de la plantilla. Pero en su lugar, está lanzando todo en la plantilla y usando ng-if , que puede causar un enlace excesivo, puede eliminar secciones del DOM de la plantilla que nunca se usarán.

Supongamos que tiene una directiva que incluirá subdirección item-first o item-second . Y la sub-directiva no cambiará para la vida de la directiva externa. Puede ajustar la plantilla, antes de llamar a la función de compilación.

<my-item data-type="first"></my-item> <my-item data-type="second"></my-item>

Y la cadena de plantilla para estos sería:

<div> <item-first></item-first> </div>

y

<div> <item-second></item-second> </div>

Estoy de acuerdo en que esto es una simplificación extrema, pero tengo algunas directivas muy complicadas y la directiva externa necesita mostrar una de, aproximadamente, 20 directivas internas diferentes basadas en un tipo. En lugar de usar transclude, puedo establecer el tipo en la directiva externa y hacer que la función de plantilla genere la plantilla correcta con la directiva interna correcta.

Esa cadena de plantilla correctamente formateada se pasa luego a la función de compilación, etc.