在浏览器中模拟离子原生支持 [英] Mocking Ionic Native Support in Browser

查看:124
本文介绍了在浏览器中模拟离子原生支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试在浏览器中模拟Ionic Native Network。为此,我在 app.module.ts 中添加了,如下所示:

Trying to mock Ionic Native Network in browser. To do so, I added the class in my app.module.ts as follows:

    ...
    import { Network } from '@ionic-native/network';
    ...
    ...    
    export class NetworkMock extends Network{      
      type = 'none';
    }
@NgModule({ ....


providers: [ 
...
...

{ provide: ErrorHandler, useClass: IonicErrorHandler },
{provide: Network, useClass: NetworkMock}

使用上述内容,当我在组件中调用以下函数时:

With the above, when I call the following function in a component:

check_network() {    
    console.log(this.net.type);    
}

我得到<浏览器控制台中的code> null

如何让它正常工作?我不应该得到'无'

How can I get it working correctly ? Am i not supposed to get 'none' ?

以下是ionic-info的输出:

The following is the output from 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

出了什么问题?请帮助。

What is going wrong ? Please help.

推荐答案

在浏览器中使用cordova插件时,我更喜欢做一些不同的事情。即使你的方法运行良好,你仍然需要手动告诉Angular在某个组件的构造函数中看到 Network 参数时应该使用哪个类。你可以在这一行中这样做:

I prefer to do things a little bit different when it comes to using a cordova plugin in the browser. Even though your approach works great, you still need to manually tell Angular which class should be used when it sees a Network parameter in some component's constructor. You do that in this line:

{ provide: Network, useClass: NetworkMock } 

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

So if you want to run the app on a mobile device, you'd need to manually change that line (and all the lines related to some other cordova plugins as well).

这就是为什么我喜欢使用 工厂提供商 。这就是我在浏览器中使用网络 cordova插件的方式:

That's why I like to use a factory provider instead. This is how I work with the Network cordova plugin in the browser:

// ------------------------------------------------------------
// 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 file:

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将使用平台信息来了解应该在我们的应用程序中使用 Network 类的哪个扩展名。

As you can see, Angular will use the Platform information to know which extension of the Network class should be used in our app.

正如我们在评论中所说:

As we talked about in the comments:

1)关于覆盖类型属性的getter,我不知道那么多的Typescript,但由于某种原因我无法设置属性的值扩展一个类时(这就是我建议使用getter的原因)。因为getter被称为就像它是属性一样,我虽然这样做并且似乎正在工作!

1) Regarding the getter to override the type property, I don't know that much of Typescript, but for some reason I was not able to set the value of a property when extending a class (that's why I suggested using the getter instead). Since a getter is called just like if it were a property, I though about doing it like that and seems to be working!

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

2) Why extending the Network class for the browser, when we could also use a class that has nothing to do with the Network class (like when you omit the extend keyword in your example? Well, you could do that, since after all this is just Javascript (and you can fix any Typescript complain using the (<any>propertyName) cast. But since you're telling Angular which implementation of the Network class should be used, why not extending that class, overriding what we want to change, but keeping everything consistent? If later the plugin add some methods that works on the browser, you won't need to change anything, since you're already using the real implementation of the plugin for all the methods that you don't override.

这篇关于在浏览器中模拟离子原生支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆