基本上我想要描述here所描述的相同行为但是在指令中工作,因为我将在整个应用程序中使用。
到目前为止,我在我的指令中得到了这个:
@Directive({
selector: '[asyncLoader]'
})
export class ActionAsyncLoader {
@Input('asyncLoader') asyncLoader: string;
...
//1 - save the text for further use.
ngOnInit(){
this.text = this.elementRef.nativeElement.innerHTML;
}
//2 - change the text when "click" is triggered
@HostListener('click', ['$event.target']) onClick(btn) {
btn.innerHTML = 'Loading';
}
//3 - change text back to the normal value
onCallbackAsync(obj){
this.elementRef.nativeElement.innerHTML = this.text;
}
}
步骤1和2目前工作正常,我的问题在第3步。我在哪里可以将我的函数绑定到在click函数上执行的事件的结尾(通常是http请求)?
答案 0 :(得分:1)
您有两个不错的选择: 1)使用输入EventEmitter 2)通过共享单件服务访问案例#3。
如果使用该指令的组件直接知道何时更改文本,那么1)可能是最好的,你可以做类似......
// in your directive
@Input() changeText: EventEmitter<any>;
ngOnInit() {
this.changeText.subscribe(event => {
// do stuff
});
}
// in your html
<div [asyncloader] changeText="myEventEmitter">
// and in your component
public myEventEmitter = new EventEmitter();
myEventEmitter.emit("change some text please");
如果其他组件可能希望以更全局的方式与所讨论的加载器进行交互,则第二个选项可以正常工作。除了在注射服务中公开EventEmitter之外,你基本上和指令中的第一个做同样的事情。然后,其他服务,组件,无论如何,都可以请求该服务进行广播,并且您的指令将知道何时进行更改。
答案 1 :(得分:0)
只想和大家分享我解决当前“挑战”的方法
@Directive({
selector: '[appSpinner]'
})
export class SpinnerDirective implements OnInit, OnChanges {
@Input() loadingState: boolean;
contentText;
constructor(private elem: ElementRef) {
if (this.elem.nativeElement.innerText !== 'undefined') {
this.contentText = this.elem.nativeElement.innerText;
}
}
ngOnInit(): void {
if (this.loadingState) {
this.elem.nativeElement.innerHTML = '<div class="spinner-border custom-spinner-btn"></div>';
}
}
ngOnChanges(changes): `void` {
this.loadingState = changes.loadingState?.currentValue;
if (this.loadingState) {
this.elem.nativeElement.innerHTML = '<div class="spinner-border custom-spinner-btn"></div>';
} else {
if (this.contentText) {
this.elem.nativeElement.innerText = this.contentText;
}
}
}
}
HTML:
<button
appSpinner
[loadingState]="true"
type="submit"
class="btn btn-primary">
LOGIN
</button>