尝试在浏览器中模拟Ionic Native Network。为此,我在 class
中添加了app.module.ts
,如下所示:
...
import { Network } from '@ionic-native/network';
...
...
export class NetworkMock extends Network{
type = 'none';
}
@NgModule({ ....
providers: [
...
...
{ provide: ErrorHandler, useClass: IonicErrorHandler },
{provide: Network, useClass: NetworkMock}
有了上述内容,当我在一个组件中调用以下函数时:
check_network() {
console.log(this.net.type);
}
我在浏览器控制台中获得null
如何让它正常工作?我不应该得到'none'
以下是ionic-info的输出:
global packages:
@ionic/cli-utils : 1.4.0
Cordova CLI : 6.5.0
Ionic CLI : 3.4.0
local packages:
@ionic/app-scripts : 1.3.0
@ionic/cli-plugin-cordova : 1.4.0
@ionic/cli-plugin-ionic-angular : 1.3.1
Cordova Platforms : none
Ionic Framework : ionic-angular 3.0.1
System:
Node : v6.9.1
OS : Windows 7
Xcode : not installed
ios-deploy : not installed
ios-sim : not installed
npm : 3.10.8
出了什么问题?请帮忙。
答案 0 :(得分:2)
在浏览器中使用cordova插件时,我更喜欢做一些不同的事情。即使你的方法运行良好,你仍然需要手动告诉Angular在某个组件的构造函数中看到Network
参数时应该使用哪个类。你这样做:
{ provide: Network, useClass: NetworkMock }
因此,如果您想在移动设备上运行该应用,则需要手动更改该行(以及与其他一些Cordova插件相关的所有行)。< / p>
这就是我喜欢使用 factory provider 的原因。这就是我在浏览器中使用Network
cordova插件的方式:
// ------------------------------------------------------------
// File: /providers/cordova-plugins/network/network.provider.ts
// ------------------------------------------------------------
// Ionic
import { Platform } from 'ionic-angular';
// Ionic native
// http://ionicframework.com/docs/v2/native/network/
import { Network } from '@ionic-native/network';
// Browser implementation
export class BrowserNetworkProvider extends Network {
public get type(): string {
return this.isOnline() ? 'wify' : 'none';
}
private isOnline(): boolean {
return navigator.onLine;
}
}
// Mobile implementation
// Is empty in this case since I don't to override anything, but in
// some other plugins, I like to add some console.log() before calling
// the methods in the plugin (by using super.nameOfTheMethod();)
export class MobileNetworkProvider extends Network {}
// ------------------------------------------------------------
// Network factory
// parameters: dependencies of the target service
// returns: instance of the service (for real devices or the browser)
// ------------------------------------------------------------
export function networkFactory(platform: Platform) {
return platform.is('cordova') ? new MobileNetworkProvider() : new BrowserNetworkProvider();
}
// networkProvider: used to import the service in the NgModule declaration
export let networkProvider =
{
provide: Network,
useFactory: networkFactory,
deps: [Platform]
};
然后在app.module.ts
文件中:
import { networkProvider } from '../providers/plugins/network/network.provider';
@NgModule({
declarations: [
MyApp,
//...
],
imports: [
// ...
],
bootstrap: [IonicApp],
entryComponents: [
// ...
],
providers: [
// Cordova plugins
networkProvider, // <- I'm using our custom provider here! :)
// ...
]
})
export class AppModule { }
正如您所看到的,Angular将使用Platform
信息来了解应在我们的应用中使用Network
类的哪个扩展名。
正如我们在评论中所谈到的那样:
1)关于覆盖type
属性的getter,我不知道很多的Typescript,但由于某种原因,我在扩展类时无法设置属性的值(这就是我建议使用吸气剂的原因)。因为getter被称为就像它是一个属性一样,我虽然这样做并且似乎正在工作!
2)为什么要扩展浏览器的Network
类,我们还可以使用与Network
类无关的类(比如省略extend
关键字时在你的例子中?你可以这样做,因为毕竟这只是Javascript(并且你可以使用(<any>propertyName)
强制转换修复任何Typescript抱怨。但是因为你告诉Angular {{{{{{应该使用1}}类,为什么不扩展该类,覆盖我们想要更改的内容,但保持一致?如果以后插件添加一些适用于浏览器的方法,则不需要更改任何内容,因为您已经使用了插件的真实实现,而不是覆盖所有方法。
答案 1 :(得分:1)
我刚刚尝试了以下替代方案工作。
...
import { Network } from '@ionic-native/network';
...
...
export class NetworkMock{
// I omitted the Extend keyword and avoided overriding the actual class
type = 'none';
}
@NgModule({ ....
providers: [
...
...
{ provide: ErrorHandler, useClass: IonicErrorHandler },
{provide: Network, useClass: NetworkMock}
使用上面的代码,现在浏览器控制台正确打印&#39; none&#39; 或我放在NetworkMock
类的type属性中的任何值。
根据我的理解,继承是Javascript本质上是棘手的,并提出了不良的情况。所以我完全避免了它。但是,在providers
数组中,我在NetworkMock
属性中引用了useClass
。
任何进一步的见解都将受到高度赞赏。