在浏览器中模拟离子原生支持

时间:2017-06-28 12:03:55

标签: ionic-framework ionic3 ionic-native

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

出了什么问题?请帮忙。

2 个答案:

答案 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

任何进一步的见解都将受到高度赞赏