1

试图在浏览器中模拟 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

出了什么问题?请帮忙。

4

2 回答 2

2

在浏览器中使用cordova插件时,我更喜欢做一些不同的事情。Network即使您的方法效果很好,您仍然需要手动告诉 Angular 当它在某些组件的构造函数中看到参数时应该使用哪个类。您在这一行中执行此操作:

{ provide: Network, useClass: NetworkMock } 

因此,如果您想在移动设备上运行该应用程序,您需要手动更改该行(以及与其他一些 cordova 插件相关的所有行)。

这就是为什么我喜欢使用工厂提供程序。这就是我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的原因)。由于 getter 就像它是一个属性一样被调用,所以我想这样做并且似乎正在工作!

2)为什么要Network为浏览器扩展类,当我们也可以使用与类无关的Network类时(比如当您在示例中省略extend关键字时?好吧,您可以这样做,因为毕竟这只是 Javascript (并且您可以使用强制转换修复任何 Typescript 抱怨(<any>propertyName)。但是既然您告诉 AngularNetwork应该使用该类的哪个实现,为什么不扩展该类,覆盖我们想要更改的内容,但保持一切一致?如果稍后插件添加一些适用于浏览器的方法,您无需更改任何内容,因为您已经在为所有未覆盖的方法使用插件的实际实现。

于 2017-06-29T07:55:50.340 回答
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}

使用上面的代码,现在浏览器控制台可以正确打印“无”或我在NetworkMock类的 type 属性中输入的任何值。

据我了解,继承是 Javascript 本质上是棘手的,并且会出现不良情况。所以我完全避免了。但是,在providers数组中我引用了我NetworkMock的 inuseClass属性。

任何进一步的见解将不胜感激

于 2017-06-28T12:46:34.467 回答