Angular 6 - 可观察订阅不起作用



>我有以下情况。服务通常从服务器获取数据,并且此数据需要在其他组件中更新。

组件仅获取一次订阅值,但服务每 2 秒获取一次数据。我测试了它,服务做对了。

就我而言,如果订阅是在 ngOnInit 中还是在构造函数中,则不会

元件:

import {Component, OnInit} from '@angular/core';
import {TaskService} from "../../services/task.service";
import {Task} from "../../models/task";
@Component({
selector: 'app-tasks',
templateUrl: './tasks.component.html',
styleUrls: ['./tasks.component.css']
})
export class TasksComponent implements OnInit {
tasks: Task[];
constructor(private taskService: TaskService) {
this.taskService.getTasks().subscribe(tasks => {  // this is triggered only once, why ?
this.tasks = tasks;
console.log(tasks);
});
}
ngOnInit() {
}
updateTask(task: Task) {
try {
task.completed = !task.completed;
this.taskService.updateTask(task).subscribe();
}
catch (e) {
task.completed = !task.completed;
}
}
}

服务:

import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {Observable, of, timer} from "rxjs";
import {Task} from "../models/task";

const httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
};

@Injectable({
providedIn: 'root'
})

export class TaskService {
tasks: Task[];
tasksURL = 'http://localhost:8080/api/tasks/';
constructor(private http: HttpClient) {
timer(1000, 2000).subscribe(() => {
this.http.get<Task[]>(this.tasksURL).subscribe(value => this.tasks = value)
}); // fetches and update the array every 2 seconds
}
getTasks(): Observable<Task[]> {
return of(this.tasks); //returns observable which is than used by the component
}
updateTask(task: Task): Observable<Task> {
const url = `${this.tasksURL}`;
return this.http.post<Task>(url, task, httpOptions)
}
}

你可以通过使用主题/行为来做你想做的事:只是你的服务中的一些变化

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
export class TaskService {
tasks: new BehaviorSubject<Task[]>([]);
tasksURL = 'http://localhost:8080/api/tasks/';
constructor(private http: HttpClient) {
timer(1000, 2000).subscribe(() => {
this.http.get<Task[]>(this.tasksURL).subscribe( (value) => { 
this.tasks.next(value);
})
}); // fetches and update the array every 2 seconds
}
getTasks(): Observable<Task[]> {
return tasks.asObservable(); //returns observable which is then used by the component
}

通过您的示例,很明显服务每 2 秒获取一次它,因为

timer(1000, 2000).subscribe(() => {

在组件中,您的订阅只是没有间隔。由于 getTask 稍后不会发出事件,因此不会更新任何内容。

要么在组件中使用计时器(不优雅(,要么手动发出.next

在役:

public myObserver$: Subject<any>;
[...]
constructor(private http: HttpClient) {
timer(1000, 2000).subscribe(() => {
this.http.get<Task[]>(this.tasksURL).subscribe(value => {
this.tasks = value;
myObserver$.next(this.tasks);
)}
}); // fetches and update the array every 2 seconds
}

然后,您可以订阅服务中的myObserver$,而不是getTasks()方法。组件中不需要计时器。

还应将订阅存储在组件中的变量中:

private subscriptionRef: Subscription;
constructor(private taskService: TaskService) {
this.subscription = this.taskService.getTasks().subscribe(tasks => {  // this is triggered only once, why ?
this.tasks = tasks;
});
}

以便您可以在 ngOnDestroy 方法中取消订阅。

ngOnDestroy(): void {
this.subscription.unsubscribe();
}

最新更新