单击返回并再次单击会抛出错误?

时间:2017-11-24 02:48:20

标签: angular firebaseui

在第一次渲染组件时,一切正常,但是当我按下浏览器后退按钮并再次点击带到该组件的链接时,它会中断。

轮廓page.module.ts

import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { ProfilePageComponent } from './profile-page.component';
import { FirebaseUIModule } from 'firebaseui-angular';
import { RouterModule, Routes } from '@angular/router';

import { AppHeaderNavbarModule } from '../../../containers/app-header-navbar';
import { ProfileNavigatorModule } from './profile-navigator';

import { MatCardModule } from '@angular/material';
import { InlineEditorModule } from 'ng2-inline-editor';

const routes: Routes = [
  { path: 'profile/:id', component: ProfilePageComponent}
];

@NgModule({
  imports: [
    CommonModule,
    FirebaseUIModule,
    FormsModule,
    MatCardModule,
    InlineEditorModule,
    AppHeaderNavbarModule,
    ProfileNavigatorModule,
    RouterModule.forChild(routes)
  ],
  declarations: [ProfilePageComponent]
})
export class ProfilePageModule {
}

轮廓page.component.ts

import { Component, OnInit, Input, ChangeDetectionStrategy } from '@angular/core';    
import { Route, ActivatedRoute } from '@angular/router';
import { UserProfile } from '../../../shared/models/user-profile';
import { AuthService } from '../../../shared/services/auth.service';
import { Observable } from 'rxjs/Observable';

import { environment } from '../../../../environments/environment';
import { constants } from '../../../../constants';

@Component({
  selector: 'profile-page',
  templateUrl: './profile-page.component.html',
  styleUrls: ['./profile-page.component.scss'],
  changeDetection: ChangeDetectionStrategy.Default
})
export class ProfilePageComponent implements OnInit {

  id: string;
  private sub: any;

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

  constructor(
    private route: ActivatedRoute,
    private authService: AuthService
  ) {
  }

  ngOnInit(): void {
      this.sub = this.route.params.subscribe(params => {
        this.id = params['id'];
      });
  }

  isLoggedin() {
    return this.authService.getCurrentUser() != null;
  }
}

错误:

core.js:1350 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'unsubscribe' of undefined
TypeError: Cannot read property 'unsubscribe' of undefined
    at FirebaseUIComponent.ngOnDestroy (index.js:132)
    at callProviderLifecycles (core.js:12434)
    at callElementProvidersLifecycles (core.js:12399)
    at callLifecycleHooksChildrenFirst (core.js:12383)
    at destroyView (core.js:13727)
    at callViewAction (core.js:13878)
    at execComponentViewsAction (core.js:13790)
    at destroyView (core.js:13726)
    at callWithDebugContext (core.js:14740)
    at Object.debugDestroyView [as destroyView] (core.js:14291)
    at FirebaseUIComponent.ngOnDestroy (index.js:132)
    at callProviderLifecycles (core.js:12434)
    at callElementProvidersLifecycles (core.js:12399)
    at callLifecycleHooksChildrenFirst (core.js:12383)
    at destroyView (core.js:13727)
    at callViewAction (core.js:13878)
    at execComponentViewsAction (core.js:13790)
    at destroyView (core.js:13726)
    at callWithDebugContext (core.js:14740)
    at Object.debugDestroyView [as destroyView] (core.js:14291)
    at resolvePromise (zone.js:824)
    at resolvePromise (zone.js:795)
    at eval (zone.js:873)
    at ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.js:4620)
    at ZoneDelegate.invokeTask (zone.js:424)
    at Zone.runTask (zone.js:192)
    at drainMicroTaskQueue (zone.js:602)
    at ZoneTask.invokeTask [as invoke] (zone.js:503)
    at invokeTask (zone.js:1540)

编辑:

问题出在父组件内,当我使用firebase-ui远离这个组件导航到其他组件时,再回来再点击其他组件,我得到上面的错误,因为

第二次按下后退按钮ngOnInit()未触发,但在尝试再次导航时ngDestroy()被触发。

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../../shared/services/auth.service';
import { FirebaseUISignInSuccess } from 'firebaseui-angular';

@Component({
  selector: 'app-home',
  template: `
          <div class="page-content">
            <firebase-ui (signInSuccess)="successCallback($event)"></firebase-ui>
            <router-outlet *ngIf="isLoggedin()"></router-outlet>
          </div>
`,
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  constructor(private authService: AuthService) {
  }

  ngOnInit(): void {
    console.log('homepage:user::' + this.authService.getCurrentUser());
  }

  successCallback(data: FirebaseUISignInSuccess) {
    console.log('data:' + data);
  }
}

3 个答案:

答案 0 :(得分:2)

@ ishandutta2007我通过可能的修复更新了插件。请试试firebaseui-angular@2.5.0

答案 1 :(得分:0)

  

订阅组件中的observable时,几乎总是如此   安排在组件销毁时取消订阅。

     

有一些特殊的可观察物,这是不必要的。   ActivatedRoute可观察量也属于例外情况。

     

ActivatedRoute及其可观察对象与路由器绝缘   本身。当路由器不再存在时,路由器会销毁它   需要注入的ActivatedRoute随之消失。

     

无论如何,请随意取消订阅。它是无害的,从来都不是坏事   实践。

所以,不要取消订阅route.params.subscribe。这将解决您的问题。

更多详情: Please Read

答案 2 :(得分:-1)

在您描述的条件下,您的问题似乎是订阅尚未初始化。您正在调用取消订阅未定义的子变量。在取消订阅之前,您应该检查该子存在。例如:

ngOnDestroy() {
  if(this.sub) {    
    this.sub.unsubscribe();
  }
}

还值得注意的是,根据文档,没有必要取消订阅ActivatedRoute上的订阅。参考:https://angular.io/guide/router#!#route-parameters

  

订阅组件中的observable时,几乎总是如此   安排在组件销毁时取消订阅。

     

有一些特殊的可观察物,这是不必要的。   ActivatedRoute可观察量也属于例外情况。

     

ActivatedRoute及其可观察对象与路由器绝缘   本身。当路由器不再存在时,路由器会销毁它   需要注入的ActivatedRoute随之消失。

     

无论如何,请随意取消订阅。它是无害的,从来都不是坏事   实践。