1

我一直在尝试将网络插件设置为应用程序上的服务,以判断是否有互联网。

在我的示例中,我设置了两个组件:

  1. 具有直接在其中实现的网络侦听器的 HOME 组件和
  2. 订阅 networkService 中的 BehaviourSubject 可观察对象的 TEST 组件

我的问题是当我从一个导航到另一个时试图破坏组件。加载应用程序的组件永远不会被破坏。即使我在 ngOnDestroy() 之上实现了类似 @HostListener('window:beforeunload') 的东西。

我已经在两个组件上实现了 ngOnDestroy 以分别删除侦听器或取消订阅 networkServices 的 observable。

我注意到,如果我在 Home 上刷新应用程序:

  1. 我导航到 TEST 并且 HOME.ngOnDestroy() 没有被调用。
  2. 当我从 TEST 导航回 HOME 时,会调用 TEST.ngOnDestroy()。

上述场景的控制台输出

如果我在 TEST 上刷新应用程序,则会发生相同的行为但相反

  1. 我导航到 HOME 并且 TEST.ngOnDestroy() 没有被调用。
  2. 当我从 HOME 导航回 TEST 时,会调用 TEST.ngOnDestroy()。

我已将项目上传到公共 git 以防万一: https ://github.com/jjgl/ionicNetworkCapacitorTests/

但这里是主要位:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Plugins, NetworkStatus, PluginListenerHandle } from '@capacitor/core';

const { Network } = Plugins;

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit, OnDestroy {
  networkStatus: NetworkStatus;
  networkListenerHome: PluginListenerHandle;

  async ngOnInit() {
    this.networkListenerHome = Network.addListener('networkStatusChange', (status) => {
      console.log("Home Page Network status changed", status);
      this.networkStatus = status;
    });

    this.networkStatus = await Network.getStatus();
  }

  ngOnDestroy() {
    console.log('home destroyed')
    this.networkListenerHome.remove();
  }
}

测试

import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { ConnectionStatus, NetworkService } from 'src/app/services/network.service';

@Component({
  selector: 'app-test-page',
  templateUrl: './test-page.page.html',
  styleUrls: ['./test-page.page.scss'],
})

export class TestPagePage implements OnInit, OnDestroy {
  subscription : Subscription
  private statusOnline : boolean;

  constructor(private networkService: NetworkService) {}

  async ngOnInit() {
    console.log('hola')
    this.subscription = this.networkService.onNetworkChange().subscribe((status: ConnectionStatus) => {
      this.statusOnline = status == ConnectionStatus.Online ? true : false;
      console.log('network change, status:', status);
    })
  }

  ngOnDestroy() { 
    console.log('test destroyed')
    this.subscription.unsubscribe()
  }

}

网络服务

import { Injectable, OnDestroy } from '@angular/core';
import { Plugins, NetworkStatus, PluginListenerHandle } from '@capacitor/core';
import { BehaviorSubject, Observable } from 'rxjs';

const { Network } = Plugins;

export enum ConnectionStatus {
  Online,
  Offline
}

@Injectable({
  providedIn: 'root'
})

export class NetworkService implements OnDestroy {

  private netStatus: BehaviorSubject<ConnectionStatus> = new BehaviorSubject(ConnectionStatus.Offline);
  networkStatus: NetworkStatus;
  networkListener: PluginListenerHandle;

  constructor() { 
    this.networkListener = Network.addListener('networkStatusChange', (status) => {
      console.log("Service Network status changed", status);
      this.networkStatus = status;
      let auxStatus = status && status.connected ? ConnectionStatus.Online : ConnectionStatus.Offline;
      this.netStatus.next(auxStatus)
    });
    this.initialState()
  }
  

  private async initialState(){
    this.networkStatus = await Network.getStatus();
    let auxStatus = this.networkStatus && this.networkStatus.connected ? ConnectionStatus.Online : ConnectionStatus.Offline;
    this.netStatus.next(auxStatus)
  }
  public onNetworkChange(): Observable<ConnectionStatus> {
    return this.netStatus.asObservable();
  }
 
  public getCurrentNetworkStatus(): ConnectionStatus {
    return this.netStatus.getValue();
  }

  ngOnDestroy(): void {
    console.log('services destroyed')
    this.networkListener.remove();
  }


}

不用说我是 Angular 的新手,所以也可以随意指出其他事情,欢迎所有评论。

PS:我已经在 networkService 上实现了 ngOnDestroy,但我没有从 TEST 调用它,因为在第一次调用 TEST.ngOnDestroy 后导航回 TEST 时服务不会重新实例化。

4

1 回答 1

3

你不能在服务中使用 Angular 生命周期。仅在组件内部使用它。

请调用Network.addListenerapp.component.ts。

...
export class AppComponent implements OnInit {
  subscription : Subscription
  private statusOnline : boolean;

  constructor(private networkService: NetworkService) {}

  async ngOnInit() {
    this.networkListener = Network.addListener('networkStatusChange', (status) => {
      console.log("Service Network status changed", status);
      this.networkStatus = status;
      let auxStatus = status && status.connected ? ConnectionStatus.Online : ConnectionStatus.Offline;
      this.networkService.netStatus.next(auxStatus) // Push the new status to NetworkService behaviorSubject
    });
  }
}

app.component.ts是一个根单例组件,因此在您刷新浏览器选项卡之前,它既不会被破坏也不会被刷新。现在您可以在任何组件中使用 NetworkService 中的网络状态,就像您已经在做的那样。

...
export class NetworkService {

  private netStatus: BehaviorSubject<ConnectionStatus> = new BehaviorSubject(ConnectionStatus.Offline);

  public onNetworkChange(): Observable<ConnectionStatus> {
    return this.netStatus.asObservable();
  }
 
  public getCurrentNetworkStatus(): ConnectionStatus {
    return this.netStatus.getValue();
  }
}
于 2020-09-23T03:04:50.437 回答