Angular 2试图在服务中实现Observable
我试图使用observable将数据从一个组件发送到另一个组件.在这里,我正在实现像这样的服务中的可观察性……
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/RX' @Injectable() export class SelectedItemService { stream1$:Observable<any>; selectedItem:JSON; stream1$= new Observable(observer=> setTimeout(() => { observer.next(this.selectedItem); },3000);) } 我的父组件正在将数据初始化为onselect()中的服务,如下所示: import { Component } from '@angular/core'; import {Http,Headers,Response } from '@angular/http'; import {Observable} from 'rxjs/Rx'; import 'rxjs/add/operator/map'; import {SelectedItemService} from './selecteditem.service' @Component({ selector: 'newcomponent',template:`<p> </p> <h2>Your Title: {{nameValue}}</h2> <ul><li *ngFor="let list of lists">Hello {{ list }}</li></ul> <form class="ui large form segment"> <h3>Add a Link</h3> <div> <label for="title">Title:</label> <input [(ngModel)]="nameValue" placeholder="title" name="Title" > </div> <label for="link">Link:</label> <input name="link"></form> <div class=container *ngFor="let data of dataServer" [class.selected]="data === selectedItem" (click)="onSelect(data)"> <div id="myimages"> <a routerLink="/SecondNewCom"> <img src="myBaseurl/{{data.images.image3}}"> </a> <router-outlet></router-outlet> </div> <div class=caption> {{data.productName}} </div> </div>`,styleUrls: [`./app/mydoc.css`] }) export class NewComponent { nameValue: string; lists: string[]; url:string; dataServer:JSON[]; length:number; selectedItem:JSON; constructor(private http:Http,public myservice:SelectedItemService) { this.myservice=myservice; this.nameValue = "declaredName"; this.url="myBaseurl"; this.lists = ['abc','xyz','lol']; this.http.get(this.url).map((res:Response) => res.json()) .subscribe( data => { this.dataServer = data this.length=Object.keys(this.dataServer).length},err => console.error(err),() => console.log('done') );} onSelect(data:JSON):void{ this.selectedItem=data; this.myservice.selectedItem=data; } } 和子组件正在接收来自订户的数据……但显示的数据未定义,我看到空白屏幕..我在哪里做错了… import {Component,Input} from '@angular/core'; import {SelectedItemService} from './selecteditem.service' @Component({ selector:'secondcomponent',template:`<h1> This is second new Component</h1> <h1>{{UiSelectedItem}}</h1> ` }) export class SecondComponent{ UiSelectedItem:JSON; constructor(public mservice:SelectedItemService) { this.mservice=mservice; mservice.stream1$.subscribe(value=>this.UiSelectedItem=value); } } 解决方法
你应该使用的是一个主题.如果你曾经使用过Angular的EventEmitter,那么这也是一个主题.使用EventEmitter,我们通常使用它来发布从子节点到父节点的事件
@Component({ template: ` <child (textChange)="onTextChange()"></child> ` }) class ParentComponent {} class ChildComponent { @Output() textChange = new EventEmitter(); onClick() { textChange.emit('new value'); } } 这是你之前使用过的,这是你需要的发布/订阅模式.有人订阅了这个活动,有人发布了它.这是我们可以使用Subject的地方.正如我所说,Eve??ntEmitter是Subject的子类. 对于这种情况,香草主题可能不够好.原因是一旦事件发出,它就永远消失了.如果没有人订阅,那么没有任何事情发生.因此,如果事件发生后你只是订阅了一个smidget,那么你什么也得不到.很多时候这是不可接受的. 对于这种情况,我们可以使用ReplaySubject.此类主题允许您保留具有可配置大小的缓冲区.因此,如果您在事件发出后立即订阅,您仍然会得到它. 这是一个例子 import { ReplaySubject } from 'rxjs/ReplaySubject'; export class SelectedItemService { private _selectedItem = new ReplaySubject<string>(1); // buffer size 1 selectedItem$= this._selectedItem.asObservable(); set selectedItem(item: string) { this._selectedItem.next(item); } } 现在,想要发布的组件只需要设置项目 service.selectedItem = 'new item'; 和订阅组件 service.selectedItem$.subscribe(item => {}) 也可以看看: > What are RxJS Subject’s and the benifits of using them? UPDATE 见Plunker (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |