Javascript 如何在Angular 2/5中从服务订阅对象?

Javascript 如何在Angular 2/5中从服务订阅对象?,javascript,angular,typescript,angular2-services,Javascript,Angular,Typescript,Angular2 Services,我遇到了一个问题,在数据从服务器发送到属性组件之后,我希望在何处将其接收到属性组件中 我在服役时做了这样的事情: private events: Event[] = []; eventChanged = new Subject<any>(); // Edit: added an observable constructor(private http: HttpClient) { this.http.get<Event[]>(this.baseUrl)

我遇到了一个问题,在数据从服务器发送到属性组件之后,我希望在何处将其接收到属性组件中

我在服役时做了这样的事情:

private events: Event[] = [];
eventChanged = new Subject<any>(); // Edit: added an observable

constructor(private http: HttpClient) { 
    this.http.get<Event[]>(this.baseUrl)
    .subscribe(events => this.events = events);
  this.eventChanged.next(this.events.slice()); //Edit: added an information to subscribers that events list changed
}
getEvents(): Observable<Event[]> {
    return this.eventChanged.asObservable();
}  // Edit: now I use this method to enables subscribers to observable

        /* I don't use that method after Edit
        showAllEvents(): Event[] {
            return [...this.events];
        }
        */
我不知道如何使
this.events
等待来自服务的数据。有什么想法吗?每一页看起来都不一样,现在我觉得自己像个傻瓜

编辑


我创建了一个subscribe和observable,但仍然
this.el.getEvents().subscribe…
没有返回组件中的任何数据

您可以在服务中创建订阅,通知事件列表是否更改

eventChanged = new Subject<Event[]>();
然后在您的服务中添加一个
next
,以便在每次任何组件更新时通知已更改的事件,并使其重新发送事件列表或您想要的任何内容

  addEvent(event: Event) {
    this.events.push(event);
    this.eventChanged.next(this.events.slice());
  }
更新:举个例子 如果我们有事件查看器、事件编辑器组件和事件服务

设置事件服务以具有主题(事件更改)、访问器(获取事件)和加法器(更新事件)

然后我们把它渲染出来

事件查看器.component.html

<ul>
  <li *ngFor="let event of events">{{event}}</li>
</ul>
并呈现一个供用户控制的按钮

event-editor.component.ts

import { Component, OnInit } from '@angular/core';
import {EventService} from '../event.service';

@Component({
  selector: 'app-event-edit',
  templateUrl: './event-edit.component.html',
  styleUrls: ['./event-edit.component.css']
})
export class EventEditComponent implements OnInit {

  eventNumber: number = 1;

  constructor(private eventService: EventService) { }

  ngOnInit() {
  }

  addEvent()
  {
    this.eventService.addEvent(this.eventNumber.toString())
    this.eventNumber++;
  }

}
<button (click)="addEvent()">Add event {{eventNumber}}</button>
然后,我们渲染这两个组件

app.component.ts

<app-event-viewer></app-event-viewer>
<app-event-edit></app-event-edit>
app.component.ts
例如:

export class YourService {
    private refreshSource: Subject<boolean> = new Subject();
    public refreshStream: Observable<boolean> = this.refreshSource.asObservable();

    endpoint_url = "https://<your_backend>/api/";

    constructor(private client: HttpClient) {}

    // get collection
    cget(queryParams: any): Promise<Obj[]> {
         return this.client.get<Obj[]>(this.endpoint_url + 'objs').toPromise();
    }

    // create one object
    post(obj: Obj): Promise<Obj> {
        const res = this.client.post(
            this.endpoint_url + 'objs',
            JSON.stringify(obj),
            this.requestParams);

        return res.toPromise().then((response) => {
            obj.id = response['id'];
            this.refreshSource.next(true);
            return obj as Obj;
        });
}



export class YourComponent implements OnDestroy {
    subscriptions: Subscription[] = [];
    success:boolean;
    failure:boolean;
    loading:boolean;

    constructor(private ys: YourService) {
        this.subscriptions.push( this.ys.refreshStrem.subscribe(() => this.load()) );
    }


    async load() {
        this.yourObjs = await this.ys.cget();
    }

    async submit() {
        this.loading = true;
        try {
            const response = this.ys.post(this.obj)
            this.success = true;   
        } catch (error) {
            console.log('error', error);
            this.failure = true;
        } finally {
            this.loading = false;
        }
    }

    ngOnDestroy() {
        this.subscriptions.forEach(subscription => subscription.unsubscribe());

}
导出类服务{
私有刷新源:主题=新主题();
public refreshStream:Observable=this.refreshSource.asObservable();
端点url=”https:///api/";
构造函数(私有客户端:HttpClient){}
//收集
cget(queryParams:any):承诺{
返回this.client.get(this.endpoint_url+'objs').toPromise();
}
//创建一个对象
邮政(obj:obj):承诺{
const res=this.client.post(
this.endpoint_url+'objs',
JSON.stringify(obj),
此参数为(s);
返回res.toPromise()。然后((响应)=>{
obj.id=响应['id'];
this.refreshSource.next(true);
将obj返回为obj;
});
}
导出类YourComponent实现OnDestroy{
订阅:订阅[]=[];
成功:布尔;
失败:布尔;
加载:布尔;
构造器(私人ys:YourService){
this.subscriptions.push(this.ys.refreshStrem.subscripte(()=>this.load());
}
异步加载(){
this.yourObjs=等待this.ys.cget();
}
异步提交(){
这是。加载=真;
试一试{
const response=this.ys.post(this.obj)
这就是成功;
}捕获(错误){
console.log('error',error);
这是失败=正确;
}最后{
这一点:加载=错误;
}
}
恩贡德斯特罗(){
this.subscriptions.forEach(subscription=>subscription.unsubscripte());
}

不幸的是,它不起作用,我在我的服务构造函数中添加了
this.eventChanged.next(this.events.slice());
,我还测试了方法
addEvent()
this.eventService.eventChanged.subscribe(..
未注意到任何更改。未再次调用它。@Adriano创建了一个完整的example@lancovici当我从服务器获取数据时,订阅不起作用。这要归功于:
events:string[]=this.eventService.getEvents();
在重新加载页面后显示数据。@Adriano检查package.json中的rxjs,并告诉我它是什么版本。检查页面时您是否看到任何错误?@lancovici它是“rxjs”:“^5.5.2”,不,我没有注意到任何错误。我进行了子脚本操作,但只有在添加下一个“事件”后才能进行
import { Component, OnInit } from '@angular/core';
import {EventService} from '../event.service';

@Component({
  selector: 'app-event-edit',
  templateUrl: './event-edit.component.html',
  styleUrls: ['./event-edit.component.css']
})
export class EventEditComponent implements OnInit {

  eventNumber: number = 1;

  constructor(private eventService: EventService) { }

  ngOnInit() {
  }

  addEvent()
  {
    this.eventService.addEvent(this.eventNumber.toString())
    this.eventNumber++;
  }

}
<button (click)="addEvent()">Add event {{eventNumber}}</button>
@NgModule({
  declarations: [
    EventViewerComponent,
    EventEditComponent
  ],
  imports: [
    CommonModule
  ],
  providers: [EventService]
})
app.component.ts

<app-event-viewer></app-event-viewer>
<app-event-edit></app-event-edit>
export class YourService {
    private refreshSource: Subject<boolean> = new Subject();
    public refreshStream: Observable<boolean> = this.refreshSource.asObservable();

    endpoint_url = "https://<your_backend>/api/";

    constructor(private client: HttpClient) {}

    // get collection
    cget(queryParams: any): Promise<Obj[]> {
         return this.client.get<Obj[]>(this.endpoint_url + 'objs').toPromise();
    }

    // create one object
    post(obj: Obj): Promise<Obj> {
        const res = this.client.post(
            this.endpoint_url + 'objs',
            JSON.stringify(obj),
            this.requestParams);

        return res.toPromise().then((response) => {
            obj.id = response['id'];
            this.refreshSource.next(true);
            return obj as Obj;
        });
}



export class YourComponent implements OnDestroy {
    subscriptions: Subscription[] = [];
    success:boolean;
    failure:boolean;
    loading:boolean;

    constructor(private ys: YourService) {
        this.subscriptions.push( this.ys.refreshStrem.subscribe(() => this.load()) );
    }


    async load() {
        this.yourObjs = await this.ys.cget();
    }

    async submit() {
        this.loading = true;
        try {
            const response = this.ys.post(this.obj)
            this.success = true;   
        } catch (error) {
            console.log('error', error);
            this.failure = true;
        } finally {
            this.loading = false;
        }
    }

    ngOnDestroy() {
        this.subscriptions.forEach(subscription => subscription.unsubscribe());

}