Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Default linking function should be a pre-linking function #2592

Closed
ProLoser opened this issue May 6, 2013 · 10 comments
Closed

Default linking function should be a pre-linking function #2592

ProLoser opened this issue May 6, 2013 · 10 comments

Comments

@ProLoser
Copy link
Contributor

ProLoser commented May 6, 2013

Sadly, I just learned the significant difference between pre-linking and post-linking functions in directives.

Namely, pre-linking goes from top to bottom (parent first, then child) where as post-linking goes in reverse (child first, then parent).

I believe that this default behavior is unusual and unexpected, and I believe that by default all linking functions should be pre-linking. I think that people are going to look at the HTML layout and expect the linking to behave in a manner that reflects this. I believe that people should only hook into this reverse, bottom-top linking behavior explicitly if they actually want to.

This might hopefully ease frustration others might encounter during development.

@petebacondarwin
Copy link
Member

Why did this cause you a problem?

On 6 May 2013 21:41, Dean Sofer notifications@github.com wrote:

Sadly, I just learned the significant difference between pre-linking and
post-linking functions in directives.

Namely, pre-linking goes from top to bottom (parent first, then child)
where as post-linking goes in reverse (child first, then parent).

I believe that this default behavior is unusual and unexpected, and I
believe that by default all linking functions should be pre-linking. I
think that people are going to look at the HTML layout and expect the
linking to behave in a manner that reflects this. I believe that people
should only hook into this reverse, bottom-top linking behavior explicitly
if they actually want to.

This might hopefully ease frustration others might encounter during
development.


Reply to this email directly or view it on GitHubhttps://github.com//issues/2592
.

@ProLoser
Copy link
Contributor Author

ProLoser commented May 6, 2013

I set a $scope variable in my parent directive (custom modal) that I was expecting to use in a child directive (select2 configuration) and instead the directive crapped out because the options object wasn't present.

<my-modal>
  <input ui-select2="myModalSelectOptions" />
</my-modal>
...
directive('myModal', fn(){
  return function($scope) {
    $scope.myModalSelectOptions = { ... };
  }
})

@MikeMcElroy
Copy link
Contributor

Could you try setting the $scope variable in a controller of the parent
directive? I'm not sure, but I think the controllers run before any of the
linking functions?

On Mon, May 6, 2013 at 2:58 PM, Dean Sofer notifications@github.com wrote:

I set a $scope variable in my parent directive (custom modal) that I was
expecting to use in a child directive (select2 configuration) and instead
the directive crapped out because the options object wasn't present.

... directive('myModal', fn(){ return function($scope) { $scope.myModalSelectOptions = { ... }; } })


Reply to this email directly or view it on GitHubhttps://github.com//issues/2592#issuecomment-17510897
.

@ProLoser
Copy link
Contributor Author

ProLoser commented May 6, 2013

I'm merely referring to the default behavior of a linking function. I'm aware how to circumvent the problem.

@colllin
Copy link

colllin commented Jul 25, 2013

@ProLoser Do you still feel that this should be changed?

It seems that you're using a linking function to define scope, which is what a controller is designed to do. Instead, it seems that a linking function is designed to be used for connecting that scope to the DOM elements - by $observe-ing data from "above", etc. In that case, you usually want the child elements to be present & ready for manipulation, which lends to the decision of making postLink the default. Please share your thoughts - I'm still learning.

@ProLoser
Copy link
Contributor Author

That's an interesting point. From all the directives I've written, I've only leveraged a controller when I wanted to give a directive a "Public API" or make methods/variables from inside of a directive directly accessible to other directives (such as when they require this directive). Otherwise, I (and I'm pretty sure most people) tend to stick with linking functions only.

Perhaps then we should instead enlighten people in the best-practice for directive development (of which I feel is fairly lacking).

However, why do you want child elements to be present and ready first? Also, isn't this a poor assumption since children may be later updated asynchronously?

Originally, I coded my directives to make 0 assumptions about children being finished, and expected them to ONLY be populated asynchronously.

@ProLoser
Copy link
Contributor Author

P.S.

I still somewhat feel a pre-linking should be default because other noobs will not expect this reverse-linking order. You look at the DOM, you KNOW the engine goes from top to bottom, parent to child. Having this happen in reverse (although is useful) is not an expected default behavior IMHO.

@colllin
Copy link

colllin commented Jul 26, 2013

Hmm... I can see a point there too. You gave me an idea... and now I don't know if I agree that returning a linking function should be any kind of default at all. I just re-wrote the example from the Writing Directives (short version) docs using a directive that defines only controller, scope, and template. No custom compiling or linking.

http://jsfiddle.net/colllin/8RuQD/

@ProLoser
Copy link
Contributor Author

Your example has 0 problems because you're not messing with DOM. Once you do, shit will hit the fan.

@btford
Copy link
Contributor

btford commented Dec 19, 2013

There's no feasible way to change this for Angular 1.x, but for 2.0 we already have many ideas on how to make directives less complex. The best we could do is improve the docs. If anyone has concrete ideas on that, feel free to submit a PR with changes. Thanks!

@btford btford closed this as completed Dec 19, 2013
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants