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

时间:2017-12-19 11:13:03

标签: angular ionic-framework dependency-injection ionic3

我正在努力将离子本机Camera服务注入我的自定义组件。我可以注入并使用它进入延迟加载的Ionic页面(即带有@IonicPage装饰器的组件)但是当我尝试创建一个使用此服务的单独组件,并在上面的页面中使用该组件时,Camera服务始终是未定义的。

我已经尝试了模块中的许多组合,以便页面和组件能够使它工作(因为我认为它与模块结构有某种关系),但它们都不适用于我。我的最新代码如下:注入自定义组件的相机最终未定义'。

基本上我的目标是拥有一个独立模块,其中包含一组使用本机离子服务的组件,可以在不同的模块/页面中重复使用。

HomePage的模块声明:

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

我可以在下面的HomePage组件中注入Camera服务,没问题:

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

我的CustomModule在这里:

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

我的CustomComponent就在这里 - 相机变量未定义。

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

1 个答案:

答案 0 :(得分:2)

NgModule的提供者数组中的所有服务都使用根注入器注册。该注射器是应用范围的。延迟加载的NgModules创建自己的根范围,因此其范围仅限于延迟加载的模块。

这就是为什么,如果你想在整个应用程序中共享服务,那么你确保只使用root(app-wide)注入器注册服务。

通过将模块直接导入AppModule并使用forRoot约定,您可以使用根注入器注册服务。应该在一个地方调用forRoot - AppModule。在其他地方使用forChild

我对Ionic不太了解,但我认为这里有两个问题。

首先,您需要通过定义静态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 {}

和CustomModule:

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

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

其次,forRoot()应始终在AppModule中注册。在其他任何地方,您都应该导入forChild()或仅导入模块(不使用forRoot)。