我有问题,我想从服务器来到我的属性组件后接收数据。
我在服务中做了这样的事情:
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];
}
*/
然后我将方法showAllEvents()
用于我的组件,如下所示:
private events: Event[] = [];
private calendarEvents: CalendarEvent[] = [];
subscription: Subscription; // Edit: Added a Subscription
getInterestedEvents() {
// this.events = this.el.showAllEvents(); <-- I changed it into observable
this.subscription = this.el.getEvents()
.subscribe(
(events) => {
this.events = events;
});
this.events.forEach(eachEvent => {
let calendarEvent: CalendarEvent = {
start: subDays(startOfDay(new Date()), 1),
end: addDays(new Date(), 1),
title: eachEvent.name,
color: colors.red
}
this.calendarEvents.push(calendarEvent);
})
}
我不知道如何让this.events
等待服务中的数据。有任何想法吗?在每一页上看起来都不一样,现在我觉得自己像个傻瓜。
编辑
我做了一个订阅和可观察,但仍然this.el.getEvents().subscribe...
不会返回我的组件中的任何数据。
您可以在服务中创建订阅,以通知事件列表是否已更改
eventChanged = new Subject<Event[]>();
在您的组件中,如果事件列表已更改,您将要订阅eventChanged
this.subscription = this.eventService.eventChanged
.subscribe(
(event: Event[]) => {
this.events = events;
}
);
然后在您的服务中添加next
,以便在每次任何组件更新时通知事件已更改,并使其重新发送事件列表或任何您想要的内容
addEvent(event: Event) {
this.events.push(event);
this.eventChanged.next(this.events.slice());
}
如果我们有事件查看器,事件编辑器组件和事件服务
设置事件服务以使主题(事件已更改),访问者(获取事件)加法器(更新事件)
import { Injectable } from '@angular/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class EventService {
eventChanged = new Subject<string[]>();
events: string[] = [
'Pizza Party',
'Hackacthon',
'Movie Night'
]
constructor() { }
addEvent(event: string) {
this.events.push(event);
this.eventChanged.next(this.events.slice());
}
getEvents() {
return this.events.slice();
}
}
然后组件EventViewer获取列表,并订阅任何更改
事件viewer.component.ts
import { Component, OnInit } from '@angular/core';
import {EventService} from '../event.service';
import {Subscription} from 'rxjs/Subscription';
@Component({
selector: 'app-event-viewer',
templateUrl: './event-viewer.component.html',
styleUrls: ['./event-viewer.component.css']
})
export class EventViewerComponent implements OnInit {
subscription: Subscription;
events: string[] = this.eventService.getEvents();
constructor(private eventService: EventService) { }
ngOnInit() {
this.subscription = this.eventService.eventChanged
.subscribe(
(events: string[]) => {
this.events = events;
}
)
}
}
那么我们就把它渲染出来
事件viewer.component.html
<ul>
<li *ngFor="let event of events">{{event}}</li>
</ul>
最后,我们需要一个事件编辑器组件
事件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++;
}
}
并呈现一个供用户控制的按钮
事件editor.component.ts
<button (click)="addEvent()">Add event {{eventNumber}}</button>
在选择的模块中,我们显然必须声明这些组件,登记提供者
app.module.ts
@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());
}