Open al-the-x opened 10 years ago
Originally taken from #1
$compile
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).
priority
attribute sets the order in which a Directive is compiled, outside in.terminal
attribute pegs priority for execution at the current priority
.<example>
element that have different priorities. Give them named compile
and pre- and post-link
functions that print their names to the console. controller
functions to each that also print their names to the console.terminal
property to see the results.The picture is this: if we add two directives to the same element, then the execution sequence is the following:
terminal
on the high-priority directive makes the other one never compile.The next step, I guess, is trying to remember what the sequence is in a complex DOM structure where directives with different priorities are assigned to different elements. Would you suggest any example that would best illustrate such a sequence?
Well, generally avoid introducing this level of complexity into your own applications and Directive chains. It's useful for Composition: breaking logic into smaller, collaborating pieces on the same element. Constrast that to traditional OOP Inheritance: children inheriting functionality from parents. On Jun 16, 2014 3:10 AM, "pomerantsev" notifications@github.com wrote:
The picture is this: if we add two directives to the same element, then the execution sequence is the following:
- both compile functions (highest to lowest priority);
- both controllers (highest to lowest);
- both pre-link functions (highest to lowest);
- both post-link functions (lowest to highest). Setting terminal on the high-priority directive makes the other one never compile.
The next step, I guess, is trying to remember what the sequence is in a complex DOM structure where directives with different priorities are assigned to different elements. Would you suggest any example that would best illustrate such a sequence?
— Reply to this email directly or view it on GitHub https://github.com/pomerantsev/angular-training/issues/2#issuecomment-46147132 .
This is what I do and don't understand about the ng-view
directives. No need to answer here - but something to talk about on Friday.
ngViewFactory
has transclude: ‘element’
. Which means: transclude the whole element including any directives defined at lower priority. (according to https://docs.angularjs.org/api/ng/service/$compile). What does it actually mean?
currentScope
- the scope in which the ngView
directive is compiled.
What is scope
equal to in the link
function? What’s the point in having scope
, currentScope
and newScope
?
If a template is defined on the given route, then a new scope is created (as a child of the directive scope, with scope.$new()
).
Then we’re creating a clone - what does this mean? What does the transclude function return? Why are we overriding the scope in $transclude
(what would the scope be if we didn’t pass one)?
currentElement
probably acts as the previous ng-view
element (since it’s stored in the closure, we get access to it next time we run the update()
function (when $routeChangeSuccess
is fired)).
What is the value of clone inside the $transclude
’s callback? Is it the same element that $transclude
returns? Does $transclude
return a jqLite-wrapped element?
Why are we assigning something to current.scope
?
What’s happening in cleanupLastView()
? What are previousElement
, currentElement
and currentScope
at the moment when this function gets called?
Why does the seconds directive get called during the $transclude
call? Comments in the code: “We need this directive so that the element content is already filled when the link function of another directive on the same element as ngView is called.” - what does this mean?
In this second directive, the ng-view
element gets filled with the template, and then this template gets compiled in the ng-view
’s scope (what is this scope at this moment? how does it relate to the new scope created in the first directive?).
Why do we set $ngControllerController
data attributes on ng-view
and all its children?
$compile
service: https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L838Trying to register a directive after the app has been bootstrapped doesn't work for me: http://plnkr.co/edit/lPIrcfqZOyOHmhjlaEyc The problem is, it is never being registered. I guess I'm doing something wrong here.
Been reading the source code and the docs. A lot of things there that I don't understand. Here are some sentences that I'd like to discuss in depth.
API reference: https://docs.angularjs.org/api/ng/service/$compile
Compiler guide: https://docs.angularjs.org/guide/compiler
Suggested homework for me (let’s discuss):
Hey @al-the-x - reminding you that you were going to give me some task to work on for me to better understand what we were talking about yesterday. Thanks!
Oh - and have a good 4th!
Thanks, Pavel. Travel safely this weekend, and I'll write down your homework this evening. Thanks for the reminder! On Jul 4, 2014 11:58 AM, "pomerantsev" notifications@github.com wrote:
Oh - and have a good 4th!
— Reply to this email directly or view it on GitHub https://github.com/pomerantsev/angular-training/issues/2#issuecomment-48058197 .
From http://plnkr.co/edit/gqBxcmGIslhcikEAnnsv
With priority: -400
:
function | arguments | file:line |
---|---|---|
compile2 | [JQLite[1], Attributes, false] | app.js:53 |
compile1 | [JQLite[1], Attributes, function] | app.js:18 |
controller1 | [] | app.js:15 |
prelink1 | [$$childScopeClass, JQLite[1], Attributes, Constructor, function] | app.js:22 |
transclude1pre | [JQLite[1], $$childScopeClass] | app.js:25 |
controller2 | [] | app.js:50 |
prelink2 | [$$childScopeClass, JQLite[1], Attributes, Constructor, undefined] | app.js:57 |
postlink2 | [$$childScopeClass, JQLite[1], Attributes, Constructor, undefined] | app.js:64 |
postlink1 | [$$childScopeClass, JQLite[1], Attributes, Constructor, function] | app.js:29 |
transclude1post | [JQLite[1], $$childScopeClass] | app.js:32 |
controller2 | [] | app.js:50 |
prelink2 | [$$childScopeClass, JQLite[1], Attributes, Constructor, undefined] | app.js:57 |
postlink2 | [$$childScopeClass, JQLite[1], Attributes, Constructor, undefined] | app.js:64 |
compile2 compile1 controller2 controller1 prelink2 transclude2pre prelink1 transclude1pre postlink1 transclude1post postlink2 transclude2post
compile2 [JQLite[1], Attributes, false] app.js:53 compile1 [JQLite[1], Attributes, function] app.js:18 controller2 [] app.js:50 controller1 [] app.js:15 prelink2 [$$childScopeClass, JQLite[1], Attributes, Constructor, function] app.js:57 transclude2pre [JQLite[1], $$childScopeClass] app.js:60 prelink1 [$$childScopeClass, JQLite[1], Attributes, Constructor, function] app.js:22 transclude1pre [JQLite[1], $$childScopeClass] app.js:25 postlink1 [$$childScopeClass, JQLite[1], Attributes, Constructor, function] app.js:29 transclude1post [JQLite[1], $$childScopeClass] app.js:32 postlink2 [$$childScopeClass, JQLite[1], Attributes, Constructor, function] app.js:64 transclude2post [JQLite[1], $$childScopeClass]
ngApp
@al-the-x - does this look good overall? https://github.com/pomerantsev/angular-training/blob/master/03-manual-stack-trace/stack-trace-01.md
Good start, yes. You might consider annotating the function calls vs the function definitions, e.g.
And so on. Any time you add another function definition to the call stack, indent. Document the params and return values of each function first, then document the functions called.
There's no need to follow these guidelines rigidly. If a simple description of a function seems sufficient, omit the detailed stack trace. Good work. Keep it up...!
Thanks! Distinguishing calls, definitions and params makes perfect sense.
This gets complicated quickly, so probably worthy of another half-hour. The two (there are actually three in that file) are collaborating to produce the effect we see as ng-view. As API consumers, we only use the ng-view Directive; the others are by-products of our usage.