Angular 2 Service vs Angular 1 Service

发布时间:2019-06-29 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Angular 2 Service vs Angular 1 Service脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

一直想写关于 Angular 1.x 与 Angular 2.x (Angular 4.x 已发布) 区别的文章,方便 Angular 1.x 的用户快速的过渡到 Angular 2.x。在浏览文章的时候,发现 Todd Motto 大神,已经写了相关的系列文章。英文好的同学,建议直接阅读 Creating an Angular 2 Injectable Service 原文哈,因为我并不打算完整地翻译,另外需要注意的是原文的示例是使用ES 2015,本文 Angular 2 示例是使用 TyPEScript哈。废话不多说,接下来我们开始进入正题。

目录

  • Angular 1.x

    • Service definITion

    • Service DI

  • Angular 2

    • Service SETUP

    • @Injectable() and DI

Angular 1.x

在 Angular 1.x 中,我们通过使用 .service() API 来创建服务。

Service Definition

我们使用 ES 2015 中的 Class 来定义服务,getToDOS() 方法只是简单地返回 Todos 列表。在后续的部分,我们会引入 HTTP 模块。

class TodoService {
  constructor() {}
  getTodos() {
    return [{
      "id": 1,
      "label": "delectus aut autem",
      "completed": false
    },{
      "id": 2,
      "label": "quis ut nam facilis et officia qui",
      "completed": false
    },{
      "id": 3,
      "label": "fugiat veniam minus",
      "completed": false
    },{
      "id": 4,
      "label": "et porro tempora",
      "completed": true
    },{
      "id": 5,
      "label": "laboriosam mollitia et enim quasi adipisci quia PRovident illum",
      "completed": false
    }];
  }
}

angular
  .module('app') // 获取已注册的app模块
  .service('TodoService', TodoService); // 通过service API注册TodoService服务

接下来我们来注入 $http 服务,在 Angular 1.x 中声明依赖项的方式有3种,分为如下:

// 方式一: 使用 $inject annotation 方式 - 严格DI
VAR fn = function (a, b) {};
fn.$inject = ['a', 'b'];

// 方式二: 使用 array-style annotations 方式 - 严格DI
var fn = ['a', 'b', function (a, b) {}];

// 方式三: 使用隐式声明方式 
var fn = function (a, b) {}; // 不推荐

我们使用第一种方式来声明依赖,具体代码如下:

class TodoService {
  constructor($http) {
    this.$http = $http;
  }
  getTodos() {
    return [{..},{..},{..},{..},{..}];
  }
}

TodoService.$inject = ['$http'];

angular
  .module('app')
  .service('TodoService', TodoService);

Service DI

const todo = {
  template: `
    <div>
      My Todo List:
      <ul>
        <li ng-repeat="todo in $ctrl.todos">
          {{ todo.label }}
        </li>
      </ul>
    </div>
  `,
  controller(TodoService) {
    $onInit() {
      this.todos = TodoService.getTodos();
    }
  }
};

上面代码中,我们在 controller 中使用 $onInit 生命周期钩子,用于在组件初始化的时候,设置组件的初始数据。示例中的 getTodos() 是同步操作,如果使用 $http 服务从远程服务器获取数据的话,返回的是一个 Promise 对象,我们就需要在 then() 方法中进行 todos 属性的赋值操作。

(备注:有兴趣了解 Angular 1.x DI 内容的话,可以参考我之前的文章 - Angular 2 DI - IoC & DI - 1 )

Angular 2

Service setup

首先定义 TodoService 服务类 (使用TypeScript):

export class TodoService {
    getTodos(): Array<{ id: number, label: string, completed: boolean }> {
        return [{
            "id": 1,
            "label": "delectus aut autem",
            "completed": false
        }, {
            "id": 2,
            "label": "quis ut nam facilis et officia qui",
            "completed": false
        }, {
            "id": 3,
            "label": "fugiat veniam minus",
            "completed": false
        }, {
            "id": 4,
            "label": "et porro tempora",
            "completed": true
        }, {
            "id": 5,
            "label": "laboriosam mollitia et enim quasi adipisci quia provident illum",
            "completed": false
        }];
    }
}

@Injectable() and DI

接下来我们使用 @Injectable 类装饰器,来装饰 TodoSevice 类:

import {Injectable} from '@angular/core';

@Injectable()
export default class TodoService {
  getTodos(): Array<{ id: number, label: string, completed: boolean }> {
    return [{..},{..},{..},{..},{..}];
  }
}

然后,我们通过 @component() 装饰器创建 todo 组件,为了跟 Angular 1.x 的示例一样,在组件初始化的时候,设置组件的初始数据,我们需要在组件中引入 OnInit 接口,并在组件类中实现该接口。具体示例如下:

import { Component, OnInit } from '@angular/core';
import { TodoService } from './services/todo.service';

@Component({
    selector: 'todo',
    template: `
    <div>
      My Todo List:
      <ul>
        <li *ngFor="let todo of todos">
          {{ todo.label }}
        </li>
      </ul>
    </div>
  `
})
export default class TodoComponent implements OnInit {
    public todos: Array<{ id: number, label: string, completed: boolean }>;

    constructor(public todoService: TodoService) { } // 使用构造方式,注入TodoService
    ngOnInit() {
        this.todos = this.todoService.getTodos(); // 获取待办事项列表
    }
}

app.COMponent.ts

import { Component } from '@angular/core';

@Component({
  selector: 'exe-app',
  template: `
    <todo></todo>
  `
})
export class AppComponent { }

app.module.ts

import { NgModule }      from '@angular/core';
import { browserModule } from '@angular/platform-browser';

import TodoComponent from './todo.component';
import { AppComponent }  from './app.component';

import { TodoService } from './services/todo.service';

@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ TodoComponent, AppComponent ],
  providers: [TodoService]
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

以上成功运行后,浏览器中的显示结果如下:

Angular 2 Service vs Angular 1 Service

我有话说

1.ngOnit 与 constructor 的区别和应用场景

在 Angular 2 中 constructor 一般用于依赖注入或执行简单的数据初始化操作,ngOnInit 钩子主要用于执行组件的其它初始化操作或获取组件输入的属性值。

详细内容请参考 - Angular 2 constructor & ngOnInit

2.@Injectable装饰器的作用

如果 TodoService 不依赖于其他对象,是可以不用使用 Injectable 类装饰器。当 TodoService 需要在构造函数中注入依赖对象,就需要使用 Injectable 类装饰器。比较推荐的做法不管是否有依赖对象,service 中都使用 Injectable 类装饰器。

详细内容请参考 - Angular 2 Inject

脚本宝典总结

以上是脚本宝典为你收集整理的Angular 2 Service vs Angular 1 Service全部内容,希望文章能够帮你解决Angular 2 Service vs Angular 1 Service所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。