简体   繁体   中英

Angular2: How to create a loading directive for a button that call an async method?

I want to create a directive for a button/link to replace its inner text by a loader when it's clicked and to re-set its inner text when the call has succeed or fail.

Here is how I start:

HTML :

<button (click)="update()" asyncLoader >Update</button> 

Directive :

import {
  Directive,
  Input,
  ElementRef,
  AfterViewInit,
  Output,
  EventEmitter,
  HostListener,
} from '@angular/core';


@Directive({
  selector: '[asyncLoader]'
})
export class ActionAsyncLoader {

  text: string;
  // @Output() valueChanged = new EventEmitter();

  constructor(private elementRef: ElementRef) {
  }

  ngOnInit(){
    this.text = this.elementRef.nativeElement.innerHTML;
    // console.log('this.text', this.text);
  }

  @HostListener('click', ['$event.target']) onClick(btn) {
    console.log('click async btn', btn);
    btn.innerHTML = 'Loading';
  }
}

Here the clicked element replaces its text by 'Loading'.

Question : Since the async method is set in a component, How to listen to the callback from here?

For now, i just emit an event on success and fail, then suscribe to it in the directive... and i pass a input in the directive to be sure it matches the callback.

HTML :

<button (click)="update()" asyncLoader='updateXYZ' >Update</button> 

Directive :

@Directive({
  selector: '[asyncLoader]'
})
export class ActionAsyncLoader {

  @Input('asyncLoader') asyncLoader: string;
  text: string;
  // @Output() valueChanged = new EventEmitter();

  constructor(private elementRef: ElementRef,
              private eventsService: EventsService) {
    eventsService.onCallbackAsync.subscribe(obj => this.onCallbackAsync(obj));
  }

  ngOnInit(){
    this.text = this.elementRef.nativeElement.innerHTML;
  }

  @HostListener('click', ['$event.target']) onClick(btn) {
    btn.innerHTML = 'Loading';
  }

  onCallbackAsync(obj){
    console.log('onCallbackAsync', obj);
    // check if directive matches the callback event
    if (this.asyncLoader === obj.asyncLoader){
      this.elementRef.nativeElement.innerHTML = this.text;
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM