【问题标题】:Angular 6 EventEmitter doesn' t workAngular 6 EventEmitter 不起作用
【发布时间】:2018-08-07 14:49:03
【问题描述】:

这是服务 服务实现了两个 EventEmitter

 @Injectable()
    export class SpinnerService implements HttpInterceptor {
        visibility: EventEmitter<boolean> = new EventEmitter(false);
        notVisibility: EventEmitter<boolean> = new EventEmitter(false);
        constructor() { }
        intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            **doesn 't work**
            this.visibility.emit(true);
            next.handle(request).subscribe(
                httpParameter => {
                    if (httpParameter instanceof HttpResponse) {
                        this.notVisibility.emit(false);
                    }
                });
            return next.handle(request);
        }
    }

这是组件

export class SpinnerComponent implements OnInit {
    visibility: boolean;
    ngOnInit() {
        this.subscribeToVisibility();
        this.subscribeToNotVisibility();
    }
    constructor(private spinnerService: SpinnerService) { }

    private subscribeToVisibility(): void {
        this.spinnerService.visibility.subscribe((value: boolean) => {
            **should enter here**
            this.visibility = value;
        });
    }
    private subscribeToNotVisibility(): void {
        this.spinnerService.notVisibility.subscribe((value: boolean) => {
            this.visibility = value;
        });
    }
}

【问题讨论】:

  • 对不起代码,请看服务,
  • 1. EventEmitters 专门用于组件@Outputs,在这里只需使用常规的Subject。 2. “不起作用”究竟是什么意思?您确定在这两种情况下都获得了相同的服务实例吗(例如,请参阅我的博客blog.jonrshar.pe/2017/Jul/15/angular-http-client.html,其中我展示了如何将相同的实例用作拦截器和注入服务)?
  • 对不起,我是一个有角度的初学者,每个服务都没有一个实例?在我老板传递的示例中没有使用@Output,无论如何我尝试过它并不起作用.我怎么知道它是否是同一个实例?
  • 我不是说你应该添加@Output,我是说你应该远离EventEmitter。不,每个服务不一定只有一个实例;如果您的类在模块providers 数组中出现两次,您需要小心确保它实际上是同一个实例。阅读那篇文章,见最后的例子。
  • EventEmitters 更改为Subjects(并将.emit(...) 调用更改为.next(...))。究竟什么“不起作用”?

标签: angular angular6 eventemitter


【解决方案1】:

我认为将 SpinnerService 与拦截器分开并创建拦截器服务要好得多,通常在你的情况下,拦截器服务没有像你提到的那样调用,检查我基于拦截器服务的微调器实现。

stackblitz demo

拦截器服务

export class InterceptorService implements HttpInterceptor {

  constructor(private spinner: SpinnerService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.spinner.visibility.emit(true);
    return next.handle(req)
      .pipe(
      delay(1000), // delay is not required just to observe the effect
      finalize(() => this.spinner.notVisibility.emit(false))
      )
  }

}

微调服务

export class SpinnerService {

  public visibility: EventEmitter<boolean> = new EventEmitter();
  public notVisibility: EventEmitter<boolean> = new EventEmitter();

}

将服务添加到 AppModule 提供者数组

app.module

@NgModule({
  imports: [BrowserModule, HttpClientModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
     { provide: HTTP_INTERCEPTORS, useClass: InterceptorService, multi: true },
    , SpinnerService
  ]
})
export class AppModule { }

组件

export class AppComponent {

  public visibility: boolean = false;

  constructor(private _http: HttpClient, private spinnerService: SpinnerService) { }

  ngOnInit() {

    this.spinnerService.visibility.subscribe(state => {
      this.visibility = state;
      console.log('visibility', state);
    });

    this.spinnerService.notVisibility.subscribe(state => {
      this.visibility = state;
      console.log('notVisibility', state);
    });

  }

  getData() { // make http request 
    this._http.get('https://jsonplaceholder.typicode.com/todos/1')
      .subscribe(console.log)
  }
}

模板

<button (click)="getData()" [disabled]="visibility">Get Data!</button>

<div>
    visibility {{visibility}}
</div>

【讨论】:

    猜你喜欢
    • 2017-10-24
    • 2020-10-04
    • 2017-01-03
    • 2020-01-19
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    相关资源
    最近更新 更多