Directive execution order in angular 2
Asked Answered
J

4

7

If I have a simple button with a click handler and a custom attribute directive like so:

<button  (click)="save()" attributedirective="project saved">Save</button>

And in my attribute directive I'm using the hostlistener decorator to listen to the click event:

@Directive({
    selector: `[attributedirective]`
})
export class AuditPusher {
    @Input('attributedirective') attributedirective: string = 'Missing message!';

    @HostListener('click', ['$event'])
    pushAudit() {
        console.log('text:'+this.attributedirective.toString());
    }
}

Which of my code will fire first? The save() on the click event or the code in my attribute directive? - And: Imagine having two attribute directives. Which of those will fire first? In Angular 1 there was something like directive priorities, how is this done in Angular 2? I find it difficult to find documentation on this.

Jubilation answered 9/8, 2016 at 10:0 Comment(0)
G
3

As far as I know the order of execution is undefined. You shouldn't depend on a specific order.

Gwenette answered 9/8, 2016 at 10:4 Comment(1)
No, that's also not defined as far as I know and explicitely so.Earpiece
D
3

I think priority concept is yet not there in Angular2. (If it is already i'm not aware of it yet) but One should not depend on a specific order as already said.

But as you have asked specifically. Order would be,

1)when page or a component is loaded, <button (click)="save()" attributedirective="project saved">Save</button> is loaded too and because of directive**(attributedirective) is attached to button, Angular2 initializes directive(attributedirective) and binds it to button.

2) As Save() is a function attached to native click (Angular2's way) event of button if you click it, it will call save() first and then it will look for other binding's events(if any) attached to it (eg.pushAudit)

Dammar answered 9/8, 2016 at 11:56 Comment(0)
G
2

A quick and dirty way around this when I had two attribute directives and Angular was executing DirectiveB before DirectiveA but I needed to have it the other way around was to delay the stuff I needed to execute last:

export class DirectiveA {
    ngOnInit() {
        doStuff();
    }
}

export class DirectiveB {
    ngOnInit() {
        setTimeout(() => {
            doMoreStuff();
        }, 0);
    }
}

When you do setTimeout(0) it will defer execution to the next Angular processing cycle, which is just what I needed in my case for everything in DirectiveA to be set up in time in order to handle events coming from DirectiveB.

Glossolalia answered 11/5, 2017 at 11:40 Comment(2)
check out ApplicationRef.tick() instead of setTimeout(0)Jubilation
Yup that could work too. I've come across it before but didn't end up using it, I'll give it a try next time, thanks!Glossolalia
S
1

I might be wrong but for me it worked like this: I have an svg:g element and added 2 directives like this: In order to execute directiveB first in the module at the exports section I added directiveB first and after directiveA.

Note that for svg the z-index is defined by the order the element appears in the document. How to use z-index in svg elements?.

I know you have a click there and a custom attribute but if you have 2 custom attributes this can work!

Sylviasylviculture answered 26/4, 2018 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.