ngIf and $compile

905 views
Skip to first unread message

Alexandre Tiertant

unread,
Feb 17, 2014, 10:10:56 AM2/17/14
to ang...@googlegroups.com
hi,

when i compile $element.contents from a directive that containing a ngIf on false statement,nothing happens.
this is because ngIf is compiling one time before removing elements and does not recompile on true statement.
is there a way to force ngIf to recompile it's content on true statement or to flush cache on removing objects from DOM ?
is it a bug of angular ?

thanks

Sander Elias

unread,
Feb 17, 2014, 10:28:16 AM2/17/14
to ang...@googlegroups.com
Hi Alexandre,

Can you show what you mean to me in a plunk or a fiddle? I do use ng-if quite often and I didn't run into those kind of issues!

Regards
Sander

Alexandre Tiertant

unread,
Feb 18, 2014, 4:31:47 AM2/18/14
to ang...@googlegroups.com
Hi, thank you for your answer,

i had reproduce my bug,you could have a look at :

see you soon
Alexandre

Sander Elias

unread,
Feb 18, 2014, 4:52:42 AM2/18/14
to ang...@googlegroups.com
Hi Alexandre,

I see your issue. However, it works as documented, your lazy method is running after the directive is compiled. the ng-if puts it back in its compiled state. the compiled state is BEFORE running the link function.
if you move your prepping and compile into the compile function, instead of in the link function, it would probably run ok.

Regards
Sander

Alexandre Tiertant

unread,
Feb 18, 2014, 6:55:19 AM2/18/14
to ang...@googlegroups.com
Hi Elias,

you are right in the case that i did not used :
$compile(element.contents())(scope);
it would be the same out of the ngIf ...because link is after directive is compiled...
this line shouldn't change the compiled state? why doesn't it work?

see you soon
Alexandre

Sander Elias

unread,
Feb 18, 2014, 7:09:04 AM2/18/14
to ang...@googlegroups.com
Hi,

No, outside the ng-if the link function works as you would expect. 
Inside is a different story. What happens is that during compile time the ng-if takes a 'snap-shot' of your bbb directive, and stores it away. 
then you come around and during link time you go an recompile stuff. that is nice and all, but then comes the ng-if, and that puts back its 'snap-shot'. And gone is your compilation.
Does this explain it a bit clearer? It's a oversimplified version of what really happens. 
If you need something like this, you can always put your aaa directive inside your ng-if, or use ng-show.

Regards
Sander

Alexandre Tiertant

unread,
Feb 18, 2014, 7:32:09 AM2/18/14
to ang...@googlegroups.com
Hi,

i understood,but as you can imagine this is not the real code i use,but it reproduce my bug.
i use requirejs to load asynchronously directives before render.
is there a way to modify my first directive to do it before ngIf compile,or to lock compile process the time to load directive,or to cleanup this 'snap-shot' ?

thank you for your explanations.
Alexandre

Sander Elias

unread,
Feb 18, 2014, 9:25:53 AM2/18/14
to ang...@googlegroups.com
Hi Alexandre,

I understood it was sample code. The problem stays the same.
What you can do, is what I told you.
  1. change your directive, so it does it's work at the compile phase, instead of during link.
  2. don't use ng-if

Regards
Sander

Alexandre Tiertant

unread,
Feb 19, 2014, 7:37:14 AM2/19/14
to ang...@googlegroups.com
Hi !
I found the solution !
in fact,this is not exactly like you explain me,all directives are not compiled at the same time,there is a priority !

thanks for your help !

Sander Elias

unread,
Feb 19, 2014, 9:06:42 AM2/19/14
to ang...@googlegroups.com
Hi Alexandre,

Priorities was in fact was one of the first things I tried to solve your issue. I must have messed that up, because now it's clearly working. Perhaps something else did change in between?
I told you I was oversimplifying, that wasn't an understatement ;) 
At least it made you look into the right direction!
Glad it worked out for you!

Regards
Sander

Alexandre Tiertant

unread,
Feb 19, 2014, 9:47:31 AM2/19/14
to ang...@googlegroups.com
Hi Elias,

but were right on compile function,i was needed to use compile function and priority to get this sample working.
working in the sample but not in the real code because requirejs load script asynchronously !
so i get back to the same problem ...
i used a settimeout to simulate the requirejs function,and need to compile to get "out of ngIf" working. ( http://plnkr.co/edit/EtfPhAVisJv4h1DL9sJU )
i tried to use tranclude with no success ! it grave me a compiled ngIf ...
so now i got a function that is execute before the ngIf compiled state but i can't stop or pause compilation or get a 'snap shot' of before compiled state...

does some one have and idea ?

thanks
Alexandre

Sander Elias

unread,
Feb 19, 2014, 9:53:22 AM2/19/14
to ang...@googlegroups.com
Hi Alexandre,


Regards
Sander

Alexandre Tiertant

unread,
Feb 19, 2014, 10:12:01 AM2/19/14
to ang...@googlegroups.com
hi,

i got this working,but the probleme is that the directive is loaded asynchronously(in the real code),so i used settimeout to simulate this ...

Sander Elias

unread,
Feb 19, 2014, 10:28:57 AM2/19/14
to ang...@googlegroups.com

Well, ok, you need some form of staging/staggering then. 
let me some fact straight before diving in further.
  1. your aaa directive is loading the bbb directive async?
  2. when it's in, you want to recompile the whole child-tree of the aaa directive?
  3. inside the aaa directive must be an ng-if.
I got that right?

Regards
Sander

Alexandre Tiertant

unread,
Feb 19, 2014, 10:53:18 AM2/19/14
to ang...@googlegroups.com
yes !
this was the solution i found,but not working with ngIf and not sure with other working like this one...

Martin Alix

unread,
Feb 19, 2014, 11:52:22 AM2/19/14
to ang...@googlegroups.com
Can you try with ng-show instead of ng-if?

Alexandre Tiertant

unread,
Feb 20, 2014, 5:02:13 AM2/20/14
to ang...@googlegroups.com
Hello Elias !

the solution was to clone element's children and remove them to append the clone in element once load is done and then compile,this way childreen are not compiled before load is done :


thanks for your help

Sander Elias

unread,
Feb 20, 2014, 7:32:52 AM2/20/14
to ang...@googlegroups.com

Alexandre

I’m glad you figured it out!
one thing, don’t clone the dom, it’s adding a lot of unneeded overhead.
replace:

var child_clone = element.children().clone();
element.children().remove();

with:

var child_clone = element.children().remove();

Regards
Sander

Alexandre Tiertant

unread,
Feb 20, 2014, 8:41:52 AM2/20/14
to ang...@googlegroups.com
thank you one more time !
Reply all
Reply to author
Forward
0 new messages