Наблюдаемый с асинхронным каналом, не обновляемым в шаблоне при объединении предметов - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть компонент, который печатает наблюдаемое значение (test $) в шаблон через асинхронный канал.

Свойство компонента необходимо инициализировать на основе входных данных компонента, поэтому я присваиваю его значение наблюдаемой, испускаемой службой (test $) в ngOnInit.Наблюдаемое, предоставляемое сервисом, присваивается комбинации субъектов при инициализации сервиса.Значение не печатается в шаблоне. Stackblitz

Если я определяю объединенные темы как BehaviorSubject, шаблон уведомляется о новом значении.

Я предполагаю, что это как-то связано с холодными / горячими наблюдаемыми.Насколько я понимаю, если вы подписываетесь на BehaviorSubject, вы всегда получите последнее значение, даже если вы подписались после того, как оно отправило значение, но с холодными наблюдаемыми (как субъект) вам необходимо подписаться до того, как значение будет отправлено, чтобы получить уведомление.

Так почему же шаблон не обновляется, если подписка происходит до того, как субъекты выдают значение?Я рассуждаю так: подписка происходит после того, как шаблон был отображен, что находится в ngOnInit.Субъекты не выдают свои значения до тех пор, пока не пройдут этот шаг.

Компонент

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  @Input() initialValue: number;
  result$: Observable<number>;

  constructor(private service: TestService) {

  }

  ngOnInit() {
    console.log('component init');
this.result$ = this.service.result$;
// Get data based on inputs
this.service.initTransformedValue(this.initialValue);
  }


}

Сервис

@Injectable()
export class TestService {


  result$: Observable<number>;
  otherValue$: Observable<number>;
  transformedValue$: Observable<number>;

  constructor() {
    console.log('service constructor');
    this.init();
  }

  init(){
    this.result$ = combineLatest(
      this.transformedValue$,
      this.otherValue$
    ).pipe(map(([first, second]) => {
        console.log('have combined value');
        return first + second;
    })
    );
  }

  initTransformedValue(initialValue) {
    // Use timeout to simulate HTTP calls
    setTimeout(() => {
      console.log('service. emit transformedValue value');
      this.transformedValue$ = of(initialValue * 2);
    }, 1000);

setTimeout(() => {
      console.log('service. emit otherValue value');
      this.otherValue$ = of(initialValue * 4);
    }, 1200);



  }

}

Шаблон

<p>{{result$ | async}}</p>

1 Ответ

0 голосов
/ 04 февраля 2019

Вы создаете новую наблюдаемую с помощью of, вам нужно, чтобы текущая наблюдаемая излучала новое значение.

https://stackblitz.com/edit/angular-fta9h1

Вы никогда не должны переназначать наблюдаемую с другой наблюдаемой, выдолжен сделать существующий наблюдаемый выброс, субъекты и субъекты поведения могут излучать, вызывая next.

const { of, BehaviorSubject } = rxjs;

let obs = of('of initial value');

obs.subscribe(val => { console.log(val); });

// This is a new observable and will not effect the subscription to a different obsevable
obs = of('of new value');

const bs = new BehaviorSubject('BehaviorSubject initial value');

bs.subscribe(val => { console.log(val); });

// This emits a new value on the same observable
bs.next('BehaviorSubject new value');
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
...