Можем ли мы подписать тему RxJ непосредственно в компоненте Angular 4? - PullRequest
0 голосов
/ 13 июня 2018

У меня есть служба 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);
    }
}

Я знаю, как будет работать код, но я хочу знать лучший и эффективный способ сделать это.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

первый способ - когда вы хотите получить данные из 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);
        }
    });
}
0 голосов
/ 13 июня 2018

Прямая подписка на ReplaySubject - это хорошо, как вы описали в первом методе.

Создание наблюдаемого из ReplaySubject и подписка на него (ваш второй метод) имеет одно преимущество.Вы не можете случайно next() значение для наблюдаемой, но это возможно в случае Subject, например ReplaySubject.Это дополнительная безопасность в стоимости немного больше кодов.

...