angular2初入视线之-service

前集回忆

上一章里我们在AppComponent里经由过程组合InputItemCheckableItemCounter三个组件,并经由过程Unidirectional Data Flow(单向数据流)的体式格局把她们驱动起来。本日这章,我们讲讲angular2里的service

本章源码:service

本章运用angular2版本为:2.4.5webpack版本为: 2.2.0

先来看看我们将要完成的结果图:

《angular2初入视线之-service》

需求剖析

(注重动画部份),在上一章的基础上我们加入了初始化数据,在数据加载完成前会有一个loading,数据准备好今后loading消逝,列表展现。

设想use case

每章都邑提一下,先设想运用场景(这类体式格局,我们称之为”BDD”,不相识的朋侪参考以BDD手写依靠注入(dependency injection))。

重构ts/app.ts

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

import {Item} from './CheckableItem';

//引入本章主题ItemService
import {ItemService} from './ItemService';

@Component({
    selector: 'my-app',
    template: `
    <h1>My First Angular 2 App</h1>
    <input-item (onItemAdded)="addItem($event)"></input-item>
    <checkable-item *ngFor="let itemInfo of items; let i = index" [item]="itemInfo" (onItemClicked)="toggle($event, i)">
    </checkable-item>
    <p *ngIf="loading">Loading</p>
    <counter *ngIf="!loading" [items]="items"></counter>
    `,
    directives: [InputItem, CheckableItem, Counter],
    //注入ItemService
    providers: [ItemService]
})
export class AppComponent implements OnInit {

    items: Item[] = [];
    //声明loading状况,初始值为true
    loading: boolean = true;

    //经由过程组织器自动猎取ItemService实例
    constructor(private _itemService: ItemService) { }

    //在组件初始化今后挪用ItemService猎取初始化数据
    ngOnInit() {
        this._itemService
            .getItems()
            .then(data => {
                //重置loading状况为false
                this.loading = false;
                //设置初始值
                this.items = data;
            });
    }

    addItem(item: Item) {
        this.items = [...this.items, item];
    }

    toggle(item: Item, index: number) {
        this.items = [
            ...this.items.slice(0, index),
            { isChecked: !item.isChecked, txt: item.txt },
            ...this.items.slice(index + 1)
        ];
    }
}

完成ItemService

touch ts/ItemService.ts

向刚建立的ts/ItemService.ts中,增加以下内容:

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

import {Item} from './CheckableItem';

//用Injectable装潢器声明该类可被依靠注入
@Injectable()
export class ItemService {

    //设置一个初始值数组
    private items: Item[] = [
        {
            isChecked: true,
            txt: 'Learn JavaScript'
        }, {
            isChecked: false,
            txt: 'Learn TypeScript'
        }, {
            isChecked: false,
            txt: 'Learn Angular2'
        }
    ];

    //供应一个要领,返回初始数据的Promise
    getItems(): Promise<Array<Item>> {
        return new Promise((resolve, reject) => {
            //这里手动做耽误是为了模仿收集要求
            setTimeout(() => {
                resolve(this.items);
            }, 1500);
        });
    }
}

检察结果

本章内容比较简朴,写到这里差不多算完毕了(实在还没有哦!),先来跑跑看

npm start

OK,我确信这个代码是能够运转的,那究竟什么是service?我们如今来对着代码讲一讲。

什么是service

  • service是可被替代的

  • service必需经由过程依靠注入运用

  • service一般用作数据存取等运用中可公用逻辑部份

怎样定义service

必需经由过程@Injectable装潢器声明

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

@Injectable()
export class ItemService {
}

运用service

引入service

import {ItemService} from './ItemService';

切忌不要自作多情的new她哦!!!!!

组织器猎取实例

constructor(private _itemService: ItemService) { }

自动注入实例

就像directives那样,增加到@Component的metadata中

providers: [ItemService]

就这么简朴,so easy 有木有?

《angular2初入视线之-service》

重构

那末我们说,到这里就完毕了吗?请看下面,template里有这么一段:

《angular2初入视线之-service》

  • 用了*ngForitems列表化

  • 用了*ngIf掌握loading的显现状况

是否是觉得有点儿矬了,假如能有个零丁的ItemList组件该多好?像如许运用:

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

import {Item} from './CheckableItem';

import {ItemService} from './ItemService';

@Component({
    selector: 'my-app',
    template: `
    <h1>My First Angular 2 App</h1>
    <input-item (onItemAdded)="addItem($event)"></input-item>
    <item-list [data]="items" (onItemClicked)="toggle($event)" [showLoading]="loading">
    </item-list>
    <counter *ngIf="!loading" [items]="items"></counter>
    `,
    providers: [ItemService]
})
export class AppComponent implements OnInit {

    items: Item[] = [];
    loading: boolean = true;

    constructor(private _itemService: ItemService) { }

    ngOnInit() {
        this._itemService
            .getItems()
            .then(data => {
                this.loading = false;
                this.items = data;
            });
    }

    addItem(item: Item) {
        this.items = [...this.items, item];
    }

    toggle(e: { item: Item, index: number }) {
        this.items = [
            ...this.items.slice(0, e.index),
            { isChecked: !e.item.isChecked, txt: e.item.txt },
            ...this.items.slice(e.index + 1)
        ];
    }
}

完成ItemList

touch ts/ItemList.ts

向刚建立的ts/ItemList.ts中,增加以下内容:

import {Component, Input, Output, EventEmitter, ChangeDetectionStrategy} from '@angular/core';

import { Item } from './CheckableItem';

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush,
    selector: 'item-list',
    template: `
    <checkable-item *ngFor="let item of data; let i=index" [item]="item" (onItemClicked)="clickItem($event, i)">
    </checkable-item>
    <p *ngIf="showLoading">Loading</p>
    `
})
export class ItemList {
    @Input() data: Item[];
    @Input() showLoading: boolean;

    @Output() onItemClicked = new EventEmitter();

    clickItem(e: Item, i: number) {
        this.onItemClicked.emit({
            item: e,
            index: i
        });
    }
}

一切都完毕了,结果依然没有变,照样很屌的模样!!!!

下回预报:运用Routing

    原文作者:leftstick
    原文地址: https://segmentfault.com/a/1190000004989637
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞