在NiceFish项目中,数据请求处理并没有用Promise的那一套方法,用的是Observable(观察者模式),我将其理解成生产者和消费者模式

如下简单例子:出自(https://segmentfault.com/a/1190000005051034)

var observable = Rx.Observable.create(function (observer) {
observer.next(1);
observer.next(2);
observer.next(3);
setTimeout(() => {
observer.next(4);
observer.complete();
}, 1000);
}); console.log('just before subscribe');
observable.subscribe({
next: x => console.log('got value ' + x),
error: err => console.error('something wrong occurred: ' + err),
complete: () => console.log('done'),
});
console.log('just after subscribe');

运行结果如下:

just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done

observer.complete()执行后observer.next()的执行是不会触发observable.subscribe里面的函数的。observer.complete()相当于终止了消费者与生产者之间的订阅关系。observable.subscribe()相当于消费者订阅了生产者的数据,一旦生产者产生了数据就会自动推送给消费者,这样会自动导致消费者根据推送过来的数据执行各自注册的函数。这是一种生产者主动,消费者被动的数据推送模式。类似于promise,但所不同的是observable能多点发射数据,能多次停止或执行subscribe里面注册的函数。

observable如何与用户点击事件关联起来呢: 参考:http://blog.csdn.net/tianjun2012/article/details/51246422

var allMoves = Rx.Observable.fromEvent(document, 'mousemove');
allMoves.subscribe(function(e) {
console.log(e.clientX, e.clientY);
}); var movesOnTheRight = allMoves.filter(function(e) {
return e.clientX > window.innerWidth / 2;
});
var movesOnTheLeft = allMoves.filter(function(e) {
return e.clientX < window.innerWidth / 2;
});
movesOnTheRight.subscribe(function(e) {
console.log('Mouse is on the right:', e.clientX);
});
movesOnTheLeft.subscribe(function(e) {
console.log('Mouse is on the left:', e.clientX);
});

以上就是observer的用法。add-comment.components组件在post-detail-main.components组件(属于post.module模块)中被引用,当add-comment.components被加载时

import .....

@Component({
selector: 'app-add-comment',
templateUrl: './add-comment.component.html',
styleUrls: ['./add-comment.component.scss']
})
export class AddCommentComponent implements OnInit {
public comments: Array<Comment>; constructor(
public commentService: CommentService,
public activeRoute: ActivatedRoute)
{ } ngOnInit() {
this.activeRoute.params.subscribe(
params => this.getCommentList(params["postId"])
);
} public getCommentList(postId: number){
this.commentService.getCommentList(postId)
.subscribe(
data => {
this.comments = data["items"]
},
error => console.error(error)
);
}
}

constructor里面的两个参数:commentService和activeRoute是两个被注入的服务,ngOnInit表示一旦组件加载完成(这里的完成是指视图加载完成,组件被编译以及初始化之后即ngOnInit是在ngOnchanges执行完之后才调用)就会执行里面的内容,所以通常模板数据的初始化可以在ngOnInit方法内执行,即在里面请求服务器数据。

ngOnInit纯粹是通知开发者组件/指令已经被初始化完成了,此时组件/指令上的属性绑定操作以及输入操作已经完成,也就是说在ngOnInit函数中我们已经能够操作组件/指令中被传入的数据了

参考:https://segmentfault.com/a/1190000012095427,http://blog.csdn.net/u010730126/article/details/64486997,https://segmentfault.com/q/1010000006040976


this.activeRoute.params:

以下是activeRoute及其属性的定义

interface RouterState {
snapshot: RouterStateSnapshot; //returns current snapshot
root: ActivatedRoute;
} interface ActivatedRoute {
snapshot: ActivatedRouteSnapshot; //returns current snapshot
url: Observable<UrlSegment[]>;
params: Observable<{[name:string]:string}>;
data: Observable<{[name:string]:any}>; queryParams: Observable<{[name:string]:string}>;
fragment: Observable<string>; root: ActivatedRout;
parent: ActivatedRout;
firstchild: ActivatedRout;
children: ActivatedRout[];
}

可以看到params是Observable的类型,事实上是angular路由监听了URL,一旦URL变化就会触发params注册的函数,那为什么params要是Observable的类型呢,在ngOnInt方法里面直接去获取URL里面的参数不可以吗,ngOnInt一定是在URl变化后执行的。

这是因为比如一个A组件,它的路由路径是/post/details/1,当A组件第一次加载到页面时,ngOnInt方法会执行,这个时候直接获取URL里面的参数是可以做到的,如下:

当某一时刻用户在页面触发了某一事件,或者js自动隔一段时间执行如下代码:this.router.navigate(['post/postdetail', '2']); 即希望URL跳转为/post/details/2;这个时候angular是不会重新加载组件的,因此ngOnInt以及constructor方法不会执行。this.snapshot的值不会变化。这个时候如果你在其他地方用到this.snapshot的引用的话是不正确的。 当然this.activeRoute.snapshot.params是变化的。如果你不介意重新像上面来一次赋值的话。

那么怎么样才能让this.snapshot的值随着URL变化而变化呢。可以将上面红框的赋值语句放到params.subscribe的参数方法里面去。这样一旦URL参数变化,this.activeRoute.params注册的方法就会执行,getCommentList()自动从服务器获取评论列表信息并显示在页面。this.snapshot这个路由参数信息随时都是有效正确的。

这里RouterStateSnapshot和ActiveRoute是对应的。它们都可以获取URl参数,但RouterStateSnapshot是一个快照,代表某一时刻页面的url参数信息。是一个固定的状态,可以通过直接赋值来获取URL的参数。URL的变化是不会触发它的更新的。而ActiveRoute是会随着URl变化而变化的路由信息状态。

注意:官网上对于params和queryParams这两个属性有了更新:

详细请参考:https://vsavkin.com/angular-router-understanding-router-state-7b5b95a12eab,https://angular.cn/guide/router,://juejin.im/entry/5822c9d6da2f60005d1af6ce

在实际页面查看两者的区别可以参考如下代码:

import { Component, OnInit, Input } from '@angular/core';
import { ActivatedRoute, Router, Params } from '@angular/router'; import { CommentService } from '../services/comment.service';
import { Comment } from '../model/comment-model'; @Component({
selector: 'app-add-comment',
templateUrl: './add-comment.component.html',
styleUrls: ['./add-comment.component.scss']
})
export class AddCommentComponent implements OnInit {
public comments: Array<Comment>;
public snapshot;
constructor(
public commentService: CommentService,
public activeRoute: ActivatedRoute,
public router: Router)
{
setTimeout(() => {
//this.router.navigate(['../', '2'], {relativeTo: this.activeRoute });
this.router.navigate(['post/postdetail', '2']);
}, 3000);
} ngOnInit() {
this.activeRoute.params.subscribe(
params => this.getCommentList(params["postId"])
);
this.snapshot = this.activeRoute.snapshot.params;
} public getCommentList(postId: number){
console.log('snapshot.params::::::::::::::::',this.snapshot);
console.log('getCommentList::::::::subscribe:::::::::::::::::::::',postId);
console.log('getCommentList:::::::::snapshot.params::::::::::::::::',this.activeRoute.snapshot.params);
this.commentService.getCommentList(postId)
.subscribe(
data => {
this.comments = data["items"]
},
error => console.error(error)
);
}
}

getCommentList方法调用了commentService服务来从服务器获取信息,那么commentService是如何发起请求的呢,里面有什么逻辑呢?

 先上源码:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions,URLSearchParams } from '@angular/http'; import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch'; import { Comment } from '../model/comment-model'; @Injectable()
export class CommentService {
public commentListURL = "mock-data/comment-mock.json"; constructor(public http: Http) { } public getCommentList(postId: number):Observable<Comment[]>{
return this.http.get(this.commentListURL)
.map((res: Response) => res.json())
}
}

 Observable<Comment[]>是代表Observable的返回类型,一旦服务器发回了数据,触发的subscrible里面注册的函数的参数为一个数组,里面的元素是Comment类型。

Http是angular内置服务,这里在构造函数里面被注入。http.get()返回的也是Observable类型的对象,它有个属性map,这个map的作用是重构服务器传回来的信息(具体请参考Observable的相关文档)。

这里的map方法也返回一个Observable的对象。res.json()就是将服务器传回来的信息对象化。

以上是一个简单的请求服务器数据的demo,可以将这个demo作为基础种子放到我们的项目中去。

以添加评论组件为例看angular2请求数据的处理的更多相关文章

  1. 【干货】2个小时教你hexo博客添加评论、打赏、RSS等功能 (转)

    备注:该教程基于Hexo 2.x版本,目前Hexo是3.x版本,照本教程实现有可能会出现404错误,笔者目前还未找时间去解决,待笔者找时间解决该问题后,再写一篇该问题的解决教程,给各位读者带来困扰,还 ...

  2. JavaScript实现点击按钮弹出输入框,点确定后添加li组件到ul组件里

    JavaScript实现点击按钮弹出输入框,点确定后添加li组件到ul组件里 <!doctype html> <html manifest="lab4.manifest&q ...

  3. 在Jekyll博客添加评论系统:gitment篇

    最近在Github Pages上使用Jekyll搭建了个人博客( jacobpan3g.github.io/cn ), 当需要添加评论系统时,找了一下国内的几个第三方评论系统,如"多说&qu ...

  4. springboot添加swagger2组件

    swagger2是一个可以构建和调试RESTful API文档的组件,利用swagger2的注解可以快速的在项目中构建Api文档,并且提供了测试API的功能 1,引入依赖 <dependency ...

  5. Vue评论组件案例

    最近学习了Vue前端框架,在这里记录一下组件的用法,我自己试着写了一个评论的组件,大神看到勿喷,欢迎提出宝贵意见. 首先看一下效果图 用到的文件有: <link rel="styles ...

  6. 雷林鹏分享:jQuery EasyUI 数据网格 - 添加分页组件

    jQuery EasyUI 数据网格 - 添加分页组件 本实例演示如何从服务器端加载数据,如何添加分页组件(pagination)到数据网格(datagrid). 创建数据网格(DataGrid) 为 ...

  7. 从零开始实现放置游戏(十三)——实现战斗挂机(4)添加websocket组件

    前两张,我们已经实现了登陆界面和游戏的主界面.不过游戏主界面的数据都是在前端写死的文本,本章我们给game模块添加websocket组件,实现前后端通信,这样,前端的数据就可以从后端动态获取到了. 一 ...

  8. svg web拓扑更新了,支持动态添加svg组件

    版本1.0请点此 预览地址 https://svg.yaolunmao.top 如何使用 # 克隆项目 git clone https://github.com/yaolunmao/vue-webto ...

  9. SpringBoot开发十九-添加评论

    需求介绍 熟悉事务管理,并且应用到添加评论的功能. 数据层:增加评论数据,修改帖子的评论数量 业务层:处理添加评论的业务,先增加评论再更新帖子的评论数量(因为用到了两个DML操作所以要用到事务管理) ...

随机推荐

  1. KVM -> 虚拟机磁盘管理_03

    1.KVM磁盘管理 1.KVM qcow2.raw.vmdk等镜像格式说明:http://blog.csdn.net/zhengmx100/article/details/53887162 raw: ...

  2. 转载:configure生成的文件(1.5.3)《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19620.html 当configure执行成功时会生成objs目录,并在该目录下产生以下目录和文件:|---ngx_auto_hea ...

  3. Linux服务器性能评估

    一.影响Linux服务器性能的因素 1. 操作系统级 CPU 内存 磁盘I/O带宽 网络I/O带宽 2. 程序应用级 二.系统性能评估标准 影响性能因素 影响性能因素 评判标准 好 坏 糟糕 CPU ...

  4. selenium捕捉视频

    捕捉视频 有时候我们未必能够分析故障只需用日志文件或截图的帮助.有时捕获完整的执行视频帮助.让我们了解如何捕捉视频. 我们将利用Monte媒体库的执行相同. 配置 第1步:导航到URL - http: ...

  5. SpringMVC(4.2):Controller接口控制器详解(2)

    原文出处: 张开涛 4.5.ServletForwardingController 将接收到的请求转发到一个命名的servlet,具体示例如下: package cn.javass.chapter4. ...

  6. SpringBoot入门小案例

    1.创建一个简单的maven project项目 2.下面来看一下项目结构: 3.pom.xml 配置jar包 <parent> <groupId>org.springfram ...

  7. 读取本地图片 BitmapImage

    BitmapImage defImage = new BitmapImage(); defImage.BeginInit(); defImage.UriSource = new Uri(@" ...

  8. linux - awk 和kill 批量杀死进程

    ps -ef|grep check_os.sh | grep -v grep | awk '{print $2}' | xargs kill -9 $2表示第2列,即进程号PID; grep -v g ...

  9. python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))

    昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...

  10. 2017-2018-2 20155225《网络对抗技术》实验八 Web基础

    2017-2018-2 20155225<网络对抗技术>实验八 Web基础 1.Web前端HTML 输入命令apachectl start打开apahce,并使用netstat -aptn ...