Цепочка обещания / каскадирование к RxJS угловому 1 к угловому 2

0

В настоящее время я пытаюсь преобразовать старые добрые $ http Promise в rxJs наблюдаемые в angular2.

Очень простой пример того, что я часто делал в угловом 1:

// Some Factory in Angular 1
var somethings = [];
var service = {
    all: all
};
return service;

function all() {
    return $http
        .get('api/somethings')
        .then(function(response) {
            somethings = parseSomethings(response.data);
            return somethings;
        });
}

// Some Controller in Angular 1
var vm = this;
vm.somethings = [];
vm.loading = true;

loadThings();

function loadThings() {
    SomeFactory
        .all()
        .then(function(somethings) {
            vm.somethings = somethings;
        })
        .finally(function() {
            vm.loading = false;
        })
}

Теперь я могу добиться чего-то подобного с угловым2, используя RxJs Observable и Subject. Но я не уверен, как вернуть "завершающие крюки" до вызывающего. (Например: загрузка в угловом контроллере)

То, что я пробовал для angular2, - это нечто похожее:

// Some Service in Angular 2
export class SomeService {
    private _somethings$: Subject<Something[]>;
    private dataStore: {
        somethings: Something[]
    };

    constructor(private http: Http) {}

    get _somethings$() : Observable<Something[]> {
        return this._somethings$.asObservable();
    }

    loadAll() {
        this.http
            .get('api/somethings')
            .map(response => response.json())
            .subscribe(
                response => {
                    this.dataStore.somethings = parseSomethings(response.data);
                    this._somethings$.next(this.dataStore.somethings);
                }
            );
    }
}

//Some Component in Angular 2
export class SomeComponent() {

    constructor(private someService: SomeService) {}

    ngOnInit() {
        this.someService.loadAll();
        this.somethings = this.someService.somethings$;
    }
}

Заметка

Я использовал тему/Наблюдаемый здесь, чтобы при создании/обновлении/удалении "что-то" я могу позвонить.next, чтобы уведомить подписчиков.

Например:

create(something: Something) : Observable<Something>{
    return this.http.post('api/somethings', JSON.stringify(something))
        .map(response => response.json())
        .do(
            something => {
                this.dataStore.somethings.push(something);
                this._somethings$.next(this.dataStore.somethings); //Notify the subscribers
            }
        );
}

Заметка

Здесь я использовал.do в методе и при вызове метода в "компоненте формы" я подписываюсь только для получения обработчика завершения:

this.someService.create(something).subscribe(
(ok) => ...
(error) => ...
() => stop loading indicator
)

Вопросов

  • Как мы можем передать завершающий крюк вызывающим абонентам (например, угловой 1 контроллер) в угловом 2 с RxJs
  • Какие альтернативные пути существуют для достижения подобного поведения?
  • 1
    Эй, я не совсем знаком с AngularJS. Но насколько я понимаю, вы хотите знать, когда функция get завершает установку loading на false? В этом случае переместите блок subscribe в вашем сервисе на свой компонент и установите там флаг loading .
  • 0
    Хорошо, я должен отписаться aswel в компоненте (скажем, после вызова create.subscribe () при нажатии кнопки)
Показать ещё 2 комментария
Теги:
angular
rxjs
promise
observable

1 ответ

2

Ваш последний пример кода в порядке. Просто используйте map() вместо subscribe() и подписаться на сайте вызова.

Вы можете использовать

return http.post(...).toPromise(val => ...))

или же

return http.post(...).map(...).toPromise(val => ...))

чтобы получить такое же поведение, как в Angular, где вы можете связать последующие вызовы с помощью .then(...)

  • 0
    Я думал об использовании карты aswel. Будет ли хорошо для этого aswel?
  • 0
    Значение, возвращаемое map() , пересылается подписчику. Если вы не хотите изменять значение, а вызываете только некоторые побочные эффекты для каждого события, то с do() все в порядке.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню