如何使用Ionic 2的角度2服务?

VIS*_*AGA 32 typescript ionic-framework ionic2 ionic3 angular

我是Ionic 2的新手.我在有角度的2文档中读到,需要在引导应用程序时注入服务.但是在通过Ionic 2教程时看不到任何引导的东西.

任何帮助都非常感谢.

Rap*_*ael 36

在Ionic2中没有使用Bootstrap(),只使用@App来声明你的应用程序.您仍需要在@Page组件中声明您的服务.

创建您的服务

import {Injectable} from "angular2/core";
import {Http} from "angular2/http";

@Injectable()
export class DataService {
  constructor(http: Http) {
    this.http = http;
    this.data = null;
  }

  retrieveData() {
    this.http.get('./mocks/test.json')
    .subscribe(data => {
      this.data = data;
    });
  }

  getData() {
    return this.data;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在@Page中使用它

import {Page} from 'ionic/ionic';
import {DataService} from './service';

@Page({
  templateUrl: 'build/test.html',
  providers: [DataService]
})
export class TestPage {
  constructor(data: DataService) {
    data.retrieveData()
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过将服务添加到`@App`提供程序数组中来实现与引导程序类似的功能,而不是**将服务添加到所述`@Page`的提供程序. (8认同)
  • 在任何需要的地方注入服务并不是一种更好的做法,这会创建一个单独的实例,这通常不是服务所需的行为.一般来说,您需要一个只在@App中注入的实例.在您的示例中,两个不同的页面将具有自己的关联实例,因此在page1中调用retrieveData()并尝试在page2中调用getData()将不会返回刚刚检索到的数据. (4认同)

seb*_*ras 24

RC更新:

从Ionic2 RC开始,现在服务应该包含在providers数组中,@NgModule以使这些服务作为单例工作(意味着将在整个应用程序中使用相同的实例).

@NgModule({
  declarations: [
    MyApp,

    // Pages
    Page1,
    Page2,

    // Pipes
    MyCustomPipe,

    // Directives
    MyCustomDirective,
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,

    // Pages
    Page1,
    Page2
  ],
  providers: [ DataService, NavigationService, Storage, ... ] // <- here!
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

旧答案(2.0.0-beta.8)

如果这可以帮助其他Ionic2开发人员,随着2.0.0-beta.8的发布,现在我们可以使用ionicBootstrap使我们的服务工作singletons意味着将在整个应用程序中使用相同的实例.

这样做所需的变化是最小的; 您的服务将保持不变

/* Notice that the imports have slightly changed*/
import {Injectable} from "@angular/core";
import {Http} from "@angular/http";
import 'rxjs/Rx';

@Injectable()
export class DataService {
  constructor(http: Http) {
    this.http = http;
    this.data = null;
  }

  retrieveData() {
    this.http.get('./mocks/test.json')
    .subscribe(data => {
      this.data = data;
    });
  }

  getData() {
    return this.data;
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,相反的注入它作为一个provider在你的Component(这将导致的一个新实例service被创建每次将component被装载)

import {Component} from '@angular/core';
import {DataService} from './service';

@Component({
  templateUrl: 'build/test.html'
  /* This should not be done anymore */
  /* providers: [DataService] */
})
export class TestPage {
  constructor(data: DataService) {
    data.retrieveData()
  }
}
Run Code Online (Sandbox Code Playgroud)

只需将其包含在ionicBootstrap您的app.ts文件中,以确保在整个应用程序中使用相同的服务实例.

ionicBootstrap(MyApp, [DataService], {});
Run Code Online (Sandbox Code Playgroud)

角度风格指南:

遵循Angular2风格指南

确保Angular 2进样器在最顶级组件处提供服务,以便共享它们.

为什么?Angular 2注射器是分层的.

为什么?在向顶级组件提供服务时,该实例是共享的,并且可供该顶级组件的所有子组件使用.

为什么?当服务共享方法或状态时,这是理想的选择.

它会工作.这不是最好的做法.引导程序提供程序选项用于配置和覆盖Angular自己的预注册服务,例如其路由支持.

因此ionicBootstrap,我们必须在我们的应用程序的最顶层组件中注册它(如果我们想在整个应用程序中使用相同的实例),而不是在其中注册服务,如下所示:

@Component({
  templateUrl: 'build/app.html',
  directives: [...],
  providers: [..., DataService]
})
class MyApp{ 
  // ...
} 
Run Code Online (Sandbox Code Playgroud)