发表于: 2019-08-19 21:55:12

0 643


今天完成的事情:

1,今天上午又写了一遍angular的英雄应用,一些概念理解清楚了

/**
  * 可观察(Observable)的数据
  * HeroService.getHeroes() 的函数签名是同步的,它所隐含的假设是 HeroService 总是能同步获取英雄列表数据。
  * 而 HeroesComponent 也同样假设能同步取到 getHeroes() 的结果。
  * 这在真实的应用中几乎是不可能的。 现在能这么做,只是因为目前该服务返回的是模拟数据。
  * 不过很快,该应用就要从远端服务器获取英雄数据了,而那天生就是异步操作。
  * HeroService 必须等服务器给出响应, 而 getHeroes() 不能立即返回英雄数据, 浏览器也不会在该服务等待期间停止响应。
  * HeroService.getHeroes() 必须具有某种形式的异步函数签名。
  * 它可以使用回调函数,可以返回 Promise(承诺),也可以返回 Observable(可观察对象)。
  * 这节课,HeroService.getHeroes() 将会返回 Observable,因为它最终会使用 Angular 的 HttpClient.get 方法来获取英雄数据,
  * 而 HttpClient.get() 会返回 Observable。
  */
/**
  * HeroService.getHeroes 方法之前返回一个 Hero[], 现在它返回的是 Observable<Hero[]>。
    你必须在 HeroesComponent 中也向本服务中的这种形式看齐。
    找到 getHeroes 方法,并且把它替换为如下代码(和前一个版本对比显示):
  */
getHeroes():void{
this.heroService.getHeroes()
.subscribe(heroes=>this.heroes = heroes);
}
/**
  * Observable.subscribe() 是关键的差异点。
上一个版本把英雄的数组赋值给了该组件的 heroes 属性。 这种赋值是同步的,
这里包含的假设是服务器能立即返回英雄数组或者浏览器能在等待服务器响应时冻结界面。
当 HeroService 真的向远端服务器发起请求时,这种方式就行不通了。
新的版本等待 Observable 发出这个英雄数组,这可能立即发生,也可能会在几分钟之后。 然后,
subscribe 函数把这个英雄数组传给这个回调函数,该函数把英雄数组赋值给组件的 heroes 属性。
使用这种异步方式,当 HeroService 从远端服务器获取英雄数据时,就可以工作了。
  */

/**
  * 在 ngOnInit 中调用它
  * 你固然可以在构造函数中调用 getHeroes(),但那不是最佳实践。
  * 让构造函数保持简单,只做初始化操作,比如把构造函数的参数赋值给属性。
  * 构造函数不应该做任何事。 它当然不应该调用某个函数来向远端服务(比如真实的数据服务)发起 HTTP 请求。
  * 而是选择在 ngOnInit 生命周期钩子中调用 getHeroes(),之后交由 Angular 处理,
  * 它会在构造出 HeroesComponent 的实例之后的某个合适的时机调用 ngOnInit。
  */
ngOnInit() {
this.getHeroes();
}

服务

/*为什么需要服务
组件不应该直接获取或保存数据,它们不应该了解是否在展示假数据。 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。
本节课,你将创建一个 HeroService,应用中的所有类都可以使用它来获取英雄列表。
不要使用 new 来创建此服务,而要依靠 Angular 的依赖注入机制把它注入到 HeroesComponent 的构造函数中。
服务是在多个“互相不知道”的类之间共享信息的好办法。 你将创建一个 MessageService,并且把它注入到两个地方:
HeroService 中,它会使用该服务发送消息。
MessagesComponent 中,它会显示其中的消息。
*/
/*
@Injectable() 服务
注意,这个新的服务导入了 Angular 的 Injectable 符号,并且给这个服务类添加了 @Injectable() 装饰器。
它把这个类标记为依赖注入系统的参与者之一。HeroService 类将会提供一个可注入的服务,
并且它还可以拥有自己的待注入的依赖。 目前它还没有依赖,但是很快就会有了。
@Injectable() 装饰器会接受该服务的元数据对象,就像 @Component() 对组件类的作用一样。
*/
/**
* HeroService 可以从任何地方获取数据:Web 服务、本地存储(LocalStorage)或一个模拟的数据源。
* 从组件中移除数据访问逻辑,意味着将来任何时候你都可以改变目前的实现方式,而不用改动任何组件。 这些组件不需要了解该服务的内部实现。
*/
import { Injectable } from '@angular/core';
//导入 Hero 和 HEROES。
import { Hero } from "./hero";
import { HEROES } from "./mock-heroes";
/**
* 提供(provide) HeroService
在要求 Angular 把 HeroService 注入到 HeroesComponent 之前,你必须先把这个服务提供给依赖注入系统。稍后你就要这么做。
你可以通过注册提供商来做到这一点。
提供商用来创建和交付服务,在这个例子中,它会对 HeroService 类进行实例化,以提供该服务。
现在,你需要确保 HeroService 已经作为该服务的提供商进行过注册。
你要用一个注入器注册它。注入器就是一个对象,负责在需要时选取和注入该提供商。
默认情况下,Angular CLI 命令 ng generate service 会通过给 @Injectable 装饰器添加元数据的形式,
用根注入器将你的服务注册成为提供商。
如果你看看 HeroService 紧前面的 @Injectable() 语句定义,就会发现 providedIn 元数据的值是 'root':
*/
@Injectable({
providedIn: 'root'
})
/**
* 当你在顶层提供该服务时,Angular 就会为 HeroService 创建一个单一的、共享的实例,并把它注入到任何想要它的类上。
* 在 @Injectable 元数据中注册该提供商,还能允许 Angular 通过移除那些完全没有用过的服务来进行优化。
*/
export class HeroService {
//添加一个 getHeroes 方法,让它返回模拟的英雄列表。
// getHeroes():Hero[]{
//   return HEROES;
// }
/** of(HEROES) 会返回一个 Observable<Hero[]>,它会发出单个值,这个值就是这些模拟英雄的数组。
  *  在 HTTP 教程中,你将会调用 HttpClient.get<Hero[]>() 它也同样返回一个 Observable<Hero[]>,
  *  它也会发出单个值,这个值就是来自 HTTP 响应体中的英雄数组。
  */
//修改 getHeroes 方法,在获取到英雄数组时发送一条消息。
getHeroes():Observable<Hero[]>{
this.messageService.add('HeroService: fetched heroes');
return of(HEROES);
}
//修改这个构造函数,添加一个私有的 messageService 属性参数。
//Angular 将会在创建 HeroService 时把 MessageService 的单例注入到这个属性中。
constructor(private messageService:MessageService) { }
}
/**
* 可观察对象版本的 HeroService
Observable 是 RxJS 库中的一个关键类。
在稍后的 HTTP 教程中,你就会知道 Angular HttpClient 的方法会返回 RxJS 的 Observable。
这节课,你将使用 RxJS 的 of() 函数来模拟从服务器返回数据。
打开 HeroService 文件,并从 RxJS 中导入 Observable 和 of 符号。
*/
import { Observable, of } from "rxjs";
//把 getHeroes 方法改成这样:
import { MessageService } from "./message.service";

明天要做到事情:写黑塔网站的页面

遇到的问题:暂无

收获:老大的话:“我们到现在仍然是一家创业公司,每天都在生死线上挣扎,始终都为了公司集体的目标而前进。


返回列表 返回列表
评论

    分享到