我们可以直接在Angular 4组件中订阅RxJs主题吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我们可以直接在Angular 4组件中订阅RxJs主题吗?相关的知识,希望对你有一定的参考价值。

我有一个Angular服务,我从后端获取数据。现在在这个服务中,我有一个ReplaySubject类型的变量。我订阅这个ReplaySubject变量到我的component

我的守则

@Injectable()
export class PersonService {
    // The person subject
    personStream: ReplaySubject<Person> = new ReplaySubject();

    // Get person from DB and add to stream
    getDataFromDB() {
        this.http.get(url).subscribe(response => {
            this.personStream.next(response.person);
        });
    }
}

@Component({...})
export class MyComponent implements OnInit {
    person: Person;

    constructor(private personService: PersonService) {}

    ngOnInit() {
        this.personService.personStream.subscribe(person => this.person = person);
    }
}

这段代码工作正常,但我有一个疑问。我见过一个与这种方法略有不同的代码。订阅ReplaySubject的另一种方法是在服务中创建一个类型为Observable的新函数,并在组件内部订阅该函数,而不是直接订阅ReplaySubject

@Injectable()
export class PersonService {
    // The person subject
    personStream: ReplaySubject<Person> = new ReplaySubject();

    // The person observable
    person$(): Observable<Person> {
        return this.personStream.asObservable();
    }

    // Get person from DB and add to stream
    getDataFromDB() {
        this.http.get(url).subscribe(response => {
            this.personStream.next(response.person);
        });
    }
}

@Component({...})
export class MyComponent implements OnInit {
    person: Person;

    constructor(private personService: PersonService) {}

    ngOnInit() {
        // Subscribe to person observable. Any time person data changes, this will be called.
        this.personService.person$().subscribe(person => this.person = person);
    }
}

我知道代码的工作方式,但我想知道这样做的最佳和最有效的方法。

谢谢。

答案

直接订阅ReplaySubject就像你在第一种方法中描述的那样。

ReplaySubject观察并订阅它(你的第二种方法)有一个好处。你不能意外地将next()的价值观察到一个可观察的但是在Subject例如ReplaySubject的情况下它是可能的。这是一些额外的安全性,代价是一些更多的代码。

另一答案

第一种方法是当你想从api获取数据并在你的组件中使用它时你只有一个主题在组件中订阅它,假设你有一个超级主题从api获取数据你有一些主题他们也是这个超级主题的观察者,他们订阅超级主题并对数据进行更改,并将naxt()更改为他们的观察者,例如,您有多个组件,这些组件具有需要数据的多个元素,组件从超级主题获取数据并订阅它和next()他们的元素。例如:

public registerObserver(name): Observable<any> {
    return this.observers[dataSourceName].observable.map((data: any) => {...}).catch((error: any) => {
        return Observable.throw({ error, name });
    });
}

public storeData(name, observable) {
    observable.subscribe(data => {
        if (this.observers[name]) {
            this.observers[name].subject.next(data);
        }
    }, error => {
        if (this.observers[name]) {
            this.observers[name].subject.error(error);
        }
    });
}

以上是关于我们可以直接在Angular 4组件中订阅RxJs主题吗?的主要内容,如果未能解决你的问题,请参考以下文章

Angular RxJS Observable:takeUntil 与使用订阅取消订阅 [关闭]

将订阅响应作为参数发送到方法 Angular/rxJs

Angular中利用rxjs库的Subject多播解决在第一次订阅时进行初始化操作(如第一次订阅时从服务器获取数据)

Angular 7 rxjs BehaviorSubject 发出重复值

如何在 Angular 和 RxJs 中管理多个顺序订阅方法?

angular 使用rxjs 监听同级兄弟组件数据变化