在 Angular Material 中使用 MdSnackBar 卡在 Observable 循环中 for Angular 2

Stuck in Observable Loop with MdSnackBar in Angular Material for Angular 2

我想在登录失败时显示一个快餐栏 'error connecting'。这很简单。但后来我希望它在 10 秒后或在操作关闭小吃店后再次尝试。但是我的 observable 立即运行,我陷入了一个无限的 observable 循环,试图在它失败后立即登录。

login.page.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { UserService, HelpersService, AuthService } from '../../services/';

@Component({
  selector: 'login-page',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss']
})
export class LoginPage {
  loginError: any;
  constructor(
    private router: Router,
    private auth: AuthService,
    public helpers: HelpersService,
  ) { }

  login() {
    this.auth.login().then((response) => {
      this.router.navigate(['/']);
    }).catch(error => {
      this.loginError = this.helpers.notify('error connecting', 'try again', 10000);
      this.helpers.notifyAction(this.loginError, this.login());
    });
  };


}

helpers.service.ts

import { Injectable } from '@angular/core';
import { MdSnackBar, MdSnackBarRef } from '@angular/material';

@Injectable()
export class HelpersService {

  constructor(public snackBar: MdSnackBar) {}

  notify(message: string, action: string, duration: number) {
    return this.snackBar.open(message, action, {duration});
  }

  notifyAction(notification: MdSnackBarRef<any>, next) {
    return notification.onAction().subscribe(() => next);
  }


}

你快到了。请在你的资源中关注我的评论。

login.page.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { UserService, HelpersService, AuthService } from '../../services/';

@Component({
  selector: 'login-page',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss']
})
export class LoginPage {
  loginError: any;
  constructor(
    private router: Router,
    private auth: AuthService,
    public helpers: HelpersService,
  ) { }

  login() {
    this.auth.login().then((response) => {
      this.router.navigate(['/']);
    }).catch(error => {
      this.loginError = this.helpers.notify('error connecting', 'try again', 10000);
      this.helpers.notifyAction(this.loginError, this.login); // no parenthesis here!
    });
  };

}

helpers.service.ts

import { Injectable } from '@angular/core';
import { MdSnackBar, MdSnackBarRef } from '@angular/material';

@Injectable()
export class HelpersService {

  constructor(public snackBar: MdSnackBar) {}

  notify(message: string, action: string, duration: number) {
    return this.snackBar.open(message, action, {duration});
  }

  notifyAction(notification: MdSnackBarRef<any>, next) {
    return notification.onAction().subscribe(() => next()); // they are here!
  }

}

Live Example Infinity Login

您需要传递函数而不是调用它。并且还通过使用箭头函数或 bind.

来关注上下文

login.page.ts

this.helpers.notifyAction(this.loginError, () => this.login());

helpers.service.ts

notifyAction(notification: MdSnackBarRef<any>, next) {
  notification.afterDismissed().subscribe(next);

  return notification.onAction().subscribe(notification.dismiss);
}