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

问题描述 投票:1回答:2

我有一个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);
    }
}

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

谢谢。

angular typescript service rxjs observable
2个回答
0
投票

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

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


0
投票

第一种方法是当你想从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);
        }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.