【问题标题】:How to use angular 2 service with Ionic 2?如何在 Ionic 2 中使用 Angular 2 服务?
【发布时间】:2016-04-18 01:22:40
【问题描述】:

我是 Ionic 2 的新手。 我阅读了 angular 2 文档,该服务需要在引导应用程序时注入。但是在浏览 Ionic 2 教程时看不到任何引导程序。

非常感谢任何帮助。

【问题讨论】:

    标签: angular typescript ionic-framework ionic2 ionic3


    【解决方案1】:

    在 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;
      }
    }
    

    然后在你的@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()
      }
    }
    

    【讨论】:

    • 您可以通过将服务添加到您的 @App 提供程序数组并将服务添加到上述 @Page 的提供程序来实现与引导程序类似的功能。
    • 是的,但最好指定您使用它们的服务。
    • 一个服务必须是一个单例,整个应用程序才能共享缓存等公共数据,这意味着它必须在顶级组件中定义。如果我们谈论的是类似服务的模型,那就是。而其他的,比如 http,则不需要相互了解。
    • 执行完这些步骤后,是否有任何线索了解如何在请求完成后访问@Page 中使用的“数据”变量?
    • 在需要的地方注入服务并不是一个更好的做法,这会创建一个单独的实例,这通常不是服务的期望行为。一般来说,您需要一个仅在@App 中注入的实例。在您的示例中,两个不同的页面将有自己的关联实例,因此在 page1 中调用 retrieveData(),并在 page2 中尝试 getData() 不会返回刚刚检索到的数据。
    【解决方案2】:

    RC 更新:

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

    @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 {}
    

    旧答案 (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;
      }
    }
    

    但不是将其作为provider 注入到您的Component 中(这将导致每次加载component 时都会创建一个service 的新实例)

    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()
      }
    }
    

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

    ionicBootstrap(MyApp, [DataService], {});
    

    Angular 风格指南:

    关注Angular2 Style Guide

    在最顶层为 Angular 2 注入器提供服务 共享它们的组件。

    为什么? Angular 2 注入器是分层的。

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

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

    还有

    它会起作用的。这不是最佳实践。 引导提供程序 选项用于配置和覆盖 Angular 自己的 预注册服务,例如其路由支持

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

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

    【讨论】:

    • 这为我修好了,非常感谢。想知道文档在哪里,很难找到关于 Promises 的模糊错误
    • 好吧,Ionic 团队仍在编写文档,但由于 Ionic2 是在 Angular2 之上构建的,您可以在 Angular Style Guides 和其他 Angular Doc 相关页面中找到这些内容。为了了解 Injector 是如何工作的(这让我能够理解这个主题并写下这个答案),你可以看看 this page
    • 嗨。我尝试按照@sebaferreras 的这个示例进行操作。似乎该服务已被拾取,但是,每当我包含该服务时,生成的屏幕都是空白的。知道为什么会这样吗?该服务位于 src/providers/global-alerts.ts
    【解决方案3】:

    搜索 Ionic Provider,在 ionic 而不是 Angular 服务中我们使用 ionic Provider,它们在 Ionic 中提供了依赖注入的概念。

    生成离子提供者

    ionic generate provider <provider name>
    

    然后在根页面或者需要使用的页面中导入provider

    并放入提供者数组

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-10
      • 2016-06-26
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      相关资源
      最近更新 更多