简体   繁体   English

在Angular4组件中使用离子本机服务

[英]Use ionic native service in Angular4 component

I am struggling to inject ionic-native Camera service into my custom component. 我正在努力将离子本机Camera服务注入到我的自定义组件中。 I can inject and use it into the lazy loaded Ionic page (ie component with @IonicPage decorator) but when I try to create a separate component that uses this service, and use that component in the above page, the Camera service is always undefined. 我可以将其注入并使用到延迟加载的Ionic页面(即具有@IonicPage装饰器的组件)中,但是当我尝试创建使用此服务的单独组件并在上一页中使用该组件时,Camera服务始终是未定义的。

I have tried many combinations within modules for both the page and the component to get it to work (as I believe its somehow related to module structure) but none of them worked for me. 我在页面和组件的模块中尝试了许多组合,以使其正常工作(因为我认为其某种程度上与模块结构有关),但没有一个适合我。 My latest code is below - the camera injected in the custom component ends up being 'undefined'. 我的最新代码如下-注入自定义组件中的相机最终被“未定义”。

Basically my goal is to have a stand alone module with set of components that use native ionic services and that can be reused across different modules/pages. 基本上,我的目标是拥有一个独立的模块,其中包含使用本机离子服务的组件集,并且可以在不同的模块/页面之间重复使用。

Module declaration for the HomePage: 主页的模块声明:

@NgModule({
  declarations: [
    HomePage
  ],
  imports: [
    IonicPageModule.forChild(HomePage),
    IonicModule,
    SharedModule, //this is module with some shared stuff
    CustomModule
  ],
  providers: [
    Camera
  ]
})
export class HomePageModule {}

I can inject Camera service into the HomePage component below no problems: 我可以在没有问题的情况下将Camera服务注入到HomePage组件中:

@IonicPage()
@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
})
export class HomePage {
  constructor(private camera: Camera) {}
}

My CustomModule is here: 我的CustomModule在这里:

@NgModule({
  declarations: [
    CustomComponent
  ],
  exports: [
    CustomComponent
  ],
  imports: [
    CommonModule,
    SharedModule,
    IonicModule.forRoot(CustomComponent)
  ],
  providers: [
    Camera
  ]
})
export class CustomModule {}

And my CustomComponent is here - camera variable is undefined. 我的CustomComponent在这里-相机变量未定义。

@Component({
  selector: 'custom-component',
  template: '<p>test</p>'
})
export class CustomComponent {
  constructor(private camera: Camera) {}
}

All services in a provider array of an NgModule are registered with the root injector. NgModule的提供程序数组中的所有服务都已向根注入器注册。 This injector is application-wide. 该注射器在整个应用范围内。 Lazy-loaded NgModules create their own root scope, and its so its scope is limited to the lazy loaded module. 延迟加载的NgModules创建它们自己的根作用域,因此其作用域仅限于延迟加载的模块。

That is why, if you want to share services across the application, that you make sure to only register services with the root (app-wide) injector. 因此,如果要在整个应用程序中共享服务,请确保仅向根(应用程序范围)注入器注册服务。

You can register services with the root injector by importing modules directly into AppModule, and using the forRoot convention. 您可以通过将模块直接导入AppModule并使用forRoot约定向根注入器注册服务。 forRoot should be called in one place - the AppModule. forRoot应该在一个位置调用-AppModule。 Use forChild everywhere else. 在其他任何地方都使用forChild

I don't know too much about Ionic, but I think there are two issues here. 我对Ionic不太了解,但我认为这里有两个问题。

First, you need to import CustomModule by defining a static forRoot method, so that Camera can be registered with the root injector: 首先,您需要通过定义静态的forRoot方法导入CustomModule,以便可以使用根注入器注册Camera:

@NgModule({
  declarations: [
    HomePage
  ],
  imports: [
    IonicPageModule.forChild(HomePage),
    IonicModule,
    SharedModule, //this is module with some shared stuff
    CustomModule // without services
  ],
  providers: [
  ]
})
export class HomePageModule {}

And CustomModule: 和CustomModule:

@NgModule({
  declarations: [
    CustomComponent
  ],
  exports: [
    CustomComponent
  ],
  imports: [
    CommonModule,
    SharedModule,
    IonicModule.forChild(CustomComponent)      
  ],
  providers: [

  ]
})
export class CustomModule {
     static forRoot():ModuleWithProviders {
         return {
             ngModule: CustomModule, 
             providers: [Camera]
         }
     }
}

Second, forRoot() should always be registered with the AppModule. 其次, forRoot()应该始终向AppModule注册。 Anywhere else, you should import forChild() or just the module (without forRoot ). 在其他任何地方,都应该导入forChild()或仅导入模块(不带forRoot )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM