Не получается значение в асинхронном канале, когда селектор толкает значение после инициализации шаблона - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть компонент Angular, который извлекает данные из службы и отображает их с помощью асинхронного канала.Служба получает данные из хранилища с помощью селектора ngrx.

Наблюдаемое в службе не излучает никаких значений.

// TestComponent

export class TestComponent {

    test$ = this.testService.test$;
    constructor() {

        this.activatedRoute.paramMap.subscribe(paramMap => {
            const id = paramMap.get('id');
            this.testService.getDetails(id);
        });
    }
}

// Шаблон TestComponent

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

// TestService

export class TestService {

    test$: Observable<string>;

    constructor(private store: Store<State>) {
    }

    getDetails(id) {
        this.test$ = this.store.select(TestSelectors.getDetailsById(id)).pipe(
            map(details => details.test)
        );
    }
}

Если вместо назначения test $ дляпреобразованное значение селектора после получения параметра URL Я делаю это, когда переменная объявляется в сервисе, значение отображается правильно в шаблоне.Так что я знаю, что это как-то связано с синхронизацией и тем, когда подписка в шаблоне имеет место по отношению к тому, когда селектор генерирует значение, но я не могу понять, что это за проблема и как ее решить.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Когда компонент создан, значение this.testService.test $ присваивается test $.

test$ = this.testService.test$;

Но testService.test $ создается только тогда, когда getDetails вызывается в вашем конструкторе.Задержка вашей переменной происходит перед вашим конструктором.

Я предполагаю, что переменная test $ имеет значение null или не определена, и что async просто об этом молчит, а не выдает исключение.

Это будетВозможное решение:

export class TestComponent {

    public test$: Observable<any>;

    constructor(private activatedRoute: ActivatedRoute) {

        this.test$ = this.activatedRoute.paramMap.pipe(
            map(paramMap => paramMap.get('id')),
            mergeMap(id => this.testService.getDetails(id))
        );
    }
}
0 голосов
/ 20 декабря 2018

Что об этом:

constructor() {

    test$ = this.activatedRoute.paramMap.pipe(
      exhaustMap(paramMap => this.testService.getDetails(paramMap.get('id')))
    )
}

и в вашем распоряжении:

getDetails(id) {
  return this.store.select(TestSelectors.getDetailsById(id)).pipe(
      map(details => details.test)
  );
}
...