Angular ngOnDestroy
Angular ngOnDestroy
我一直在尝试将网络插件设置为应用程序上的服务,以判断是否有互联网。
在我的示例中,我设置了两个组件:
- HOME 组件,其中直接实现了网络侦听器并且
- 订阅 networkService 中可观察到的 BehaviourSubject 的 TEST 组件
我的问题是当我从一个导航到另一个时试图破坏组件。加载应用程序的组件永远不会被销毁。即使我在 ngOnDestroy().
之上实现了类似 @HostListener('window:beforeunload') 的东西
我已经在两个组件上实现了 ngOnDestroy 以分别删除侦听器或取消订阅 networkServices 的可观察对象。
我注意到如果我在主页上刷新应用:
- 我导航到 TEST 并且 HOME.ngOnDestroy() 没有被调用。
- 当我从 TEST 导航回 HOME 时,TEST.ngOnDestroy() 被调用。
如果我在测试时刷新应用程序,会发生相同的行为但相反
- 我导航到主页,但未调用 TEST.ngOnDestroy()。
- 当我从主页导航回测试时,TEST.ngOnDestroy() 被调用。
我已将项目上传到 public 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 时服务没有被重新实例化第一次。
您不能在服务中使用 Angular 生命周期。仅在组件内部使用它。
请将Network.addListener
调成app.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 中的 netstatus。
...
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();
}
}
我一直在尝试将网络插件设置为应用程序上的服务,以判断是否有互联网。
在我的示例中,我设置了两个组件:
- HOME 组件,其中直接实现了网络侦听器并且
- 订阅 networkService 中可观察到的 BehaviourSubject 的 TEST 组件
我的问题是当我从一个导航到另一个时试图破坏组件。加载应用程序的组件永远不会被销毁。即使我在 ngOnDestroy().
之上实现了类似 @HostListener('window:beforeunload') 的东西我已经在两个组件上实现了 ngOnDestroy 以分别删除侦听器或取消订阅 networkServices 的可观察对象。
我注意到如果我在主页上刷新应用:
- 我导航到 TEST 并且 HOME.ngOnDestroy() 没有被调用。
- 当我从 TEST 导航回 HOME 时,TEST.ngOnDestroy() 被调用。
如果我在测试时刷新应用程序,会发生相同的行为但相反
- 我导航到主页,但未调用 TEST.ngOnDestroy()。
- 当我从主页导航回测试时,TEST.ngOnDestroy() 被调用。
我已将项目上传到 public 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 时服务没有被重新实例化第一次。
您不能在服务中使用 Angular 生命周期。仅在组件内部使用它。
请将Network.addListener
调成app.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 中的 netstatus。
...
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();
}
}