2016-06-06 4 views
3

я мог бы быть отключен от процесса, но здесь идет:Как создать наблюдаемую в наблюдаемой в Angular2

У меня есть сервис angular2. Источником данных этой службы будет localstorage ... позже опционально обновляется, когда вызов БД с использованием HTTP возвращается. Потому что я хочу обновить данные, возвращенные при возвращении различных источников, кажется, я хочу использовать наблюдаемые. На данный момент я просто пытаюсь убрать эту концепцию, поэтому я пропустил аспект localstorage ... но я включил «предысторию», поэтому он (некоторые) понимает, почему я хочу делать это в нескольких методах.

Я думал, что у меня будет метод getHTTPEvents(), который возвратит наблюдаемое значение с полезной нагрузкой, являющейся событиями из БД. (Теория в том, что в какой-то момент в будущем, я бы также иметь 'getLSEvents() метод, который бы поросенок обратно туда)

издеваться, что до, у меня есть этот код:

private eventsUrl = 'app/mock-events.json'; 
getHTTPEvents() : Observable<Array<any>> { 
    return this._http.get(this.eventsUrl) 
     .map(response => response.json()['events']) 
     .catch(this.handleError); // handle error is a logging method 
} 

Моей целью было бы создать метод, который позволяет фильтровать возвращаемые события, но все же возвращает наблюдаемые пользователям услуги. Вот где моя проблема. С этой целью у меня есть открытый метод, который будет вызываться пользователями службы. (Пытались использовать шаблон здесь https://coryrylan.com/blog/angular-2-observable-data-services)

public getEvents(key:string,value:string) : Observable<Array<any>> { 
    var allEventsObserve : Observable<Array<any>> = this.getHTTPEvents(); 
    var filteredEventsObserve : Observable<Array<any>>; 


    allEventsObserve 
    .subscribe(
     events => { 
      for(var i=0;i<events.length;i++) { 
       if(events[i][key]==value) { 
        console.log('MATCH!!!' + events[i][key]); // THIS WORKS! 
        return new Observable(observer => filteredEventsObserve = observer); // what do I need to return here? I want to return an observable so the service consumer can get updates 
       } 
      } 
      return allEventsObserve 
     }, 
     error => console.error("Error retrieving all events for filtering: " + error)); 

}

выше не работает. Я смотрю множество видеороликов и читаю много учебников об наблюдаемых, но ничего, что я могу найти, похоже, больше отличается от создания и использования HTTP-наблюдаемого.

Далее я попробовал этот способ получения новой наблюдаемой:

var newObs = Observable.create(function (observer) { 
        observer.next(events[i]); 
        observer.complete(events[i]); 
       }); 

И хотя по крайней мере, компилирует, я не знаю, как «возврат» его в нужное время ... как я могу 't «Создать» это вне метода allEventsObserve.subscribe (потому что «событий» не существует) и не может (кажется) «вернуть» его из подписки. Я также не совсем уверен, как тогда я буду запускать «следующий» ...?

Нужно ли мне изменять данные внутри allEventsObserve и как-то просто вернуть это? Могу ли я сделать новое наблюдаемое (как было сделано выше) правильную полезную нагрузку - и если да, то как мне его вызвать? и т. д. Я проверил здесь: How to declare an observable on angular2, но, похоже, не следит за тем, как срабатывает «вторая» наблюдаемая. Возможно, у меня есть парадигма?

+0

Чтобы сохранить googling, api для Observable.create находится здесь: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/create.md – lowcrawler

ответ

1

Похоже, вы не понимаете, что оператор RxJS (например, map, и т. Д.) На самом деле возвращается, и я думаю, что исправление, которое сделает решение понятным.

Рассмотрим небольшой пример:

allEventsObserve 
    .map(events => { 
    return 'this was an event'; 
    }) 

Конечно, это довольно бесполезный пример, так как все данные из events теряется, но давайте игнорировать, что на данный момент. Результат вышеприведенного кода не является массивом строк или чего-то еще, это на самом деле другой Observable. Этот Observable просто испустит строку 'this was an event' для каждого массива событий, испущенных allEventsObserve. Это позволяет нам связывать операторы с наблюдаемыми - каждый оператор в цепочке возвращает новый Observable, который испускает элементы, которые были каким-то образом изменены оператор.

allEventsObserve 
    .map(events => { 
    return 'this was an event'; 
    }) 
    .filter(events => typeof events !== 'undefined') 

allEventsObserve, очевидно, Observable, allEventsObserve.map() вычисляется в Observable, и так же allEventsObserve.map().filter().

Итак, поскольку вы ожидаете, что ваша функция вернет Observable, вы еще не хотите звонить подписки, так как это приведет к возврату того, что на самом деле не является Observable.

Имея это в виду, что ваш код можно переписать следующим образом:

public getEvents(key:string,value:string) : Observable<Array<any>> { 
    var allEventsObserve : Observable<Array<any>> = this.getHTTPEvents(); 

    return allEventsObserve 
     .map(events => { 
      var match = events.filter(event => event[key] == value); 
      if (match.length == 0) { 
      throw 'no matching event found'; 
      } else { 
      return match[0]; 
      } 
     }) 
     .catch(e => { 
     console.log(e); 
     return e; 
     }); 

} 

Так как getEvents, возвращает Observable, где-то в вашем коде вы могли бы сделать что-то вроде getEvents().subscribe(events => processEvents()) взаимодействовать с ними. Этот код также предполагает, что this.getHTTPEvents() возвращает Observable.

Также обратите внимание, что я изменил цикл for на вызов filter, который работает с массивами. events в этом случае является обычным JavaScript Array, поэтому filter, получивший вызов, не является тем же filter, что и оператор RxJS filter.

+0

Спасибо, с твиком (уловка должна что-то вернуть) и typo (match! = match), что сработало! Однако у меня остается вопрос - в .map есть оператор return, который возвращает стандартный объект (соответствует [0]) ... пока .map (как я понимаю) должен вернуть Observable. ? Далее, как бы я в итоге объединил два наблюдаемых в один - как мне в конечном итоге понадобится (вызов LS и вызов в БД)? Возможно, это другое дело в разное время. Благодаря! – lowcrawler

+1

Функция, переданная в '.map', называется' observer'. «Наблюдатель», переданный в '.map', возвращает объекты JavaScript, которые определяют, какие элементы будут испускаться' наблюдаемым'. 'allEventsObserve.map()' возвращает (или, может быть, точнее сказать «оценивает») «наблюдаемый», который испускает объекты, возвращаемые в «наблюдателе», переданные в '.map'. Я надеюсь, что в этом есть смысл. –

+0

Я не уверен, что вы пытаетесь сделать, но [zip] (http://reactivex.io/documentation/operators/zip.html) может быть тем, что вы ищете для merge.two observables. –

Смежные вопросы