Pregunta Enlace vs compilar vs controlador


Cuando crea una directiva, puede poner código en el compilador, la función de enlace o el controlador.

En los documentos, explican que:

  • función de compilación y enlace se utilizan en diferentes fases de la angular ciclo
  • los controladores se comparten entre las directivas

Sin embargo, para mí no está claro, qué tipo de código debería ir a dónde.

E.g .: ¿Puedo crear funciones en compilación y tenerlas adjuntas al alcance en el enlace o solo adjuntar funciones al alcance en el controlador?

¿Cómo se comparten los controladores entre las directivas, si cada directiva puede tener su propio controlador? ¿Los controladores realmente se comparten o son solo las propiedades del alcance?


508
2018-03-28 07:48


origen


Respuestas:


Compilar: 

Esta es la fase en la que Angular realmente compila su directiva. Esta función de compilación se llama solo una vez para cada referencia a la directiva dada. Por ejemplo, supongamos que está utilizando la directiva ng-repeat. ng-repeat tendrá que buscar el elemento al que está conectado, extraer el fragmento html al que está conectado y crear una función de plantilla.

Si ha utilizado HandleBars, las plantillas de subrayado o equivalentes, es como compilar sus plantillas para extraer una función de plantilla. Para esta función de plantilla, pasa los datos y el valor de retorno de esa función es el html con los datos en los lugares correctos.

La fase de compilación es ese paso en Angular que devuelve la función de plantilla. Esta función de plantilla en angular se llama función de enlace.

Fase de enlace: 

La fase de enlace es donde se adjuntan los datos ($ scope) a la función de enlace y debe devolver el html vinculado. Dado que la directiva también especifica dónde va este html o qué cambia, ya está listo. Esta es la función en la que desea realizar cambios en el html vinculado, es decir, el html que ya tiene los datos adjuntos. En angular, si escribe código en la función de enlace, generalmente es la función de enlace posterior (por defecto). Es una especie de devolución de llamada a la que se llama después de que la función de vinculación haya vinculado los datos con la plantilla.

Controlador :

El controlador es un lugar donde pones cierta lógica específica de directiva. Esta lógica también puede entrar en la función de vinculación, pero luego tendría que poner esa lógica en el alcance para que sea "compartible". El problema con eso es que estarías corrompiendo el alcance con tus directivas, lo que en realidad no es algo que se espera. Entonces, ¿cuál es la alternativa si dos Directivas quieren comunicarse entre sí / cooperar entre sí? Por supuesto, usted puede poner toda esa lógica en un servicio y luego hacer que ambas directivas dependan de ese servicio, pero eso solo genera una dependencia más. La alternativa es proporcionar un Controlador para este alcance (generalmente ¿alcance aislado?) Y luego este controlador se inyecta en otra directiva cuando esa directiva "requiere" la otra. Ver pestañas y paneles en la primera página de angularjs.org para ver un ejemplo.


454
2018-03-28 11:58



Quería agregar también lo que el libro de O'Reily AngularJS del equipo de Google tiene que decir:

Controlador: cree un controlador que publique una API para comunicarse entre directivas. Un buen ejemplo es Directiva a la Comunicación Directiva

Enlace: modifique mediante programación las instancias de elemento DOM resultantes, agregue detectores de eventos y configure el enlace de datos.

Compilar: modifique mediante programación la plantilla DOM para las funciones en las copias de una directiva, como cuando se usa en ng-repeat. Su función de compilación también puede devolver funciones de enlace para modificar las instancias de elementos resultantes.


95
2018-06-04 19:59



UN directive le permite extender el vocabulario HTML de manera declarativa para crear componentes web. los ng-app atributo es una directiva, por lo que es ng-controller y todo el ng- prefixed attributes. Las directivas pueden ser attributes, tags o incluso class  names, comments.

Cómo nacen las directivas (compilation y instantiation)

Compilar: Usaremos el compile función para ambos manipulate el DOM antes de que se represente y devuelva un link función (que manejará el enlace para nosotros). Este también es el lugar para poner cualquier método que deba compartirse con todos los instances de esta directiva.

enlazar: Usaremos el link función para registrar a todos los oyentes en un elemento DOM específico (clonado de la plantilla) y configurar nuestros enlaces a la página.

Si se establece en el compile() función que solo se han establecido una vez (que es a menudo lo que desea). Si se establece en el link() función que se establecerán cada vez que el elemento HTML está vinculado a los datos en el  objeto.

<div ng-repeat="i in [0,1,2]">
    <simple>
        <div>Inner content</div>
    </simple>
</div>

app.directive("simple", function(){
   return {
     restrict: "EA",
     transclude:true,
     template:"<div>{{label}}<div ng-transclude></div></div>",        
     compile: function(element, attributes){  
     return {
             pre: function(scope, element, attributes, controller, transcludeFn){

             },
             post: function(scope, element, attributes, controller, transcludeFn){

             }
         }
     },
     controller: function($scope){

     }
   };
});

Compile la función devuelve el pre y post función de enlace. En la función de enlace previo tenemos la plantilla de instancia y también el alcance del controller, pero aún la plantilla no está sujeta al alcance y aún no tiene contenido transcluido.

Post función de enlace es donde el enlace de publicación es la última función para ejecutar. Ahora el transclusion Esta completo, the template is linked to a scope, y el view will update with data bound values after the next digest cycle. los link la opción es solo un atajo para configurar un post-link función.

controlador: El controlador de directivas puede pasarse a otra fase de vinculación / compilación de directivas. Se puede inyectar en otras directivas como un medio para usar en la comunicación inter-directiva.

Debe especificar el nombre de la directiva que se requerirá: debe estar vinculada al mismo elemento o su elemento primario. El nombre puede ser prefijado con:

? – Will not raise any error if a mentioned directive does not exist.
^ – Will look for the directive on parent elements, if not available on the same element.

Use el corchete [‘directive1′, ‘directive2′, ‘directive3′] para requerir controlador de directivas múltiples.

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope, $element) {
});

app.directive('parentDirective', function() {
  return {
    restrict: 'E',
    template: '<child-directive></child-directive>',
    controller: function($scope, $element){
      this.variable = "Hi Vinothbabu"
    }
  }
});

app.directive('childDirective', function() {
  return {
    restrict:  'E',
    template: '<h1>I am child</h1>',
    replace: true,
    require: '^parentDirective',
    link: function($scope, $element, attr, parentDirectCtrl){
      //you now have access to parentDirectCtrl.variable
    }
  }
});

45
2017-09-29 14:07



Además, una buena razón para usar una función de controlador vs. enlace (ya que ambos tienen acceso al alcance, elemento y atributos) se debe a que puede pasar cualquier servicio o dependencia disponible a un controlador (y en cualquier orden), mientras que no puedes hacer eso con la función de enlace. Observe las diferentes firmas:

controller: function($scope, $exceptionHandler, $attr, $element, $parse, $myOtherService, someCrazyDependency) {...

vs.

link: function(scope, element, attrs) {... //no services allowed

10
2017-11-07 15:47



esta es una buena muestra para comprender las fases directivas http://codepen.io/anon/pen/oXMdBQ?editors=101

var app = angular.module('myapp', [])

app.directive('slngStylePrelink', function() {
    return {
        scope: {
            drctvName: '@'
        },
        controller: function($scope) {
            console.log('controller for ', $scope.drctvName);
        },
        compile: function(element, attr) {
            console.log("compile for ", attr.name)
            return {
                post: function($scope, element, attr) {
                    console.log('post link for ', attr.name)
                },
                pre: function($scope, element, attr) {
                    $scope.element = element;
                    console.log('pre link for ', attr.name)
                        // from angular.js 1.4.1
                    function ngStyleWatchAction(newStyles, oldStyles) {
                        if (oldStyles && (newStyles !== oldStyles)) {
                            forEach(oldStyles, function(val, style) {
                                element.css(style, '');
                            });
                        }
                        if (newStyles) element.css(newStyles);
                    }

                    $scope.$watch(attr.slngStylePrelink, ngStyleWatchAction, true);

                    // Run immediately, because the watcher's first run is async
                    ngStyleWatchAction($scope.$eval(attr.slngStylePrelink));
                }
            };
        }
    };
});

html

<body ng-app="myapp">
    <div slng-style-prelink="{height:'500px'}" drctv-name='parent' style="border:1px solid" name="parent">
        <div slng-style-prelink="{height:'50%'}" drctv-name='child' style="border:1px solid red" name='child'>
        </div>
    </div>
</body>

9
2017-07-18 15:28



  • compilar: se usa cuando necesitamos modificar la plantilla de directiva, como agregar nueva expresión, agregar otra directiva dentro de esta directiva
  • controlador: utilizado cuando necesitamos compartir / reutilizar datos de $ scope
  • enlazar: es una función que se usa cuando necesitamos adjuntar controlador de eventos o para manipular DOM.

2
2018-06-22 14:50