AngularJS orden incorrecto de funciones de enlace

If I include a directive inside another directive's template and transclude the contents into it then its link function gets called before any of the transcluded directives.

For example (also on JSFiddle):

I have the following HTML composed of directives and templates.

<body ng-app="showcase">
    <reel>
        <asset></asset>
    </reel>

    <script type="text/ng-template" id="reel.html">
      <div class="reel">
        <div class="inner" scrollable ng-transclude></div>
      </div>
    </script>

    <script type="text/ng-template" id="asset.html">
      <div class="asset" ng-transclude></div>
    </script>
</body>

And set up my directives like so.

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

app.directive('reel', function() {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    templateUrl:'reel.html',
    link: function() { console.log('reel'); }
  };
});

app.directive('scrollable', function() {
  return {
    terminal: true,
    restrict: 'A',
    link: function() { console.log("scrollable"); }
  };
});

app.directive('asset', function() {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    templateUrl: 'asset.html',
    link: function() { console.log('asset'); }
  };
});

The expected output into the console would be:

asset
scrollable
reel

Gracias asset es hijo de scrollable, however I get:

scrollable
asset
reel

Does anyone know how I can get my order back but still define the additional directive within the reel ¿plantilla?

preguntado el 28 de mayo de 14 a las 12:05

If you are using directives on the same element you need to set the priority. By default user defined directives are priority of 0. Try setting asset to priority: 10. -

@CorySilva I used the terminal attribute to state its priority is always last. ngTransclude had a priority of 0 apparently. -

@CorySilva Actually that worked... but it's weird the terminal property didn't. Do you want to make an answer and I will accept? -

@CorySilva Sorry comment overload... I misunderstood the terminal property... it means any later priorities won't run. I thought it meant make it of latest priority no matter what. -

Oops, I did not even notice you had the terminal property; I had the same first impressions of that property as well. Glad you got it to work! -

1 Respuestas

If you are using directives on the same element you need to set the priority. By default user defined directives are priority of 0. Try setting asset to priority: 10.

Taken from AngularJS Code Comments:

/** ### Directive Definition Object
 *
 * The directive definition object provides instructions to the {@link ng.$compile
 * compiler}. The attributes are:
 *
 * #### `priority`
 * When there are multiple directives defined on a single DOM element, sometimes it
 * is necessary to specify the order in which the directives are applied. The `priority` is used
 * to sort the directives before their `compile` functions get called. Priority is defined as a
 * number. Directives with greater numerical `priority` are compiled first. Pre-link functions
 * are also run in priority order, but post-link functions are run in reverse order. The order
 * of directives with the same priority is undefined. The default priority is `0`.
 *
 * #### `terminal`
 * If set to true then the current `priority` will be the last set of directives
 * which will execute (any directives at the current priority will still execute
 * as the order of execution on same `priority` is undefined).
 */

Respondido el 20 de junio de 20 a las 10:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.