Можно ли воссоздать поведение ngIf и асинхронного канала в файле компонента? - PullRequest
0 голосов
/ 24 января 2019

У меня есть два компонента, компонент формы и страница благодарности. (Полный список кодов приведен здесь: Как правильно обмениваться данными между двумя компонентами с помощью rxjs ReplaySubject? )

Я работаю с наблюдаемыми с помощью ngIf и асинхронного канала следующим образом:

<div *ngIf='(message$ | async) as msg'>
...
</div>

Это шаблон страницы с благодарностью, и он отлично работает.

Что бы я хотелДостигнуть сейчас: если пользователь достигнет страницы благодарности, для сообщения $ не будет значения, тогда я бы хотел перенаправить пользователя к содержимому формы.Я пытаюсь воспроизвести поведение шаблона (без сообщения $, ничего не отображается) в компоненте, поэтому я могу перенаправить пользователя на компонент формы с помощью router.navigate ().

Любая помощь будет оценена, спасибо заранее!

Примечание: я подписываюсь на одну и ту же наблюдаемую дважды, одна подписка будет обрабатываться асинхронным каналом, другая должна обрабатываться компонентом.Есть ли более эффективный способ сделать это?

Ответы [ 3 ]

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

Я использовал ReplaySubject вместо BehaviorSubject. Это было неправильно, в конце концов, я опустил самую важную часть. BehaviorSubject полезен для проверки того, как значение изменяется со временем.

Я переключился на BehaviorSubject, потому что он всегда будет выдавать последнее значение при подписке, поэтому нет необходимости добавлять какую-либо дополнительную логику или выдавать какие-либо дополнительные значения, или проверять, является ли наблюдаемое «пустым».

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

Я думаю, что вы не должны использовать его внутри файла TS, так как асинхронный канал делает подписку и отписку автоматически без утечек.В вашем случае команда Angular просто предлагает использовать излучатели и входные данные для обмена данными между компонентами (и, в основном, с использованием интеллектуальных компонентов, единственные компоненты могут работать и обмениваться данными с другими, также существует стратегия обмена данными с сервисами, которой я не являюсь.большое веселье).Пример для обмена данными между двумя компонентами с использованием эмиттеров и входов путем передачи через родительский элемент:
- componentA:

<!-- template -->
{{ localVar }}
<button (click)="onSendToParent()">Send localVar to parent</button>

И

// typescript
localVar = 'could be anything - objects - strings - numbers';
@Ouput() componentAoutput: EventEmitter<string> = new EventEmitter<string>();

onSendToParent(): void {
    this.componentAoutput.emit(this.localVar);
}

- Родитель:

<!-- template -->
{{ fromComponentA$ | async }}
<component-a (componentAoutput)="fromComponentA$.next($event)"></component-a>
<component-b [componentBinput]="fromComponentA$ | async"></component-b>

И

// typescript
fromComponentA$: BehaviourSubject<string> = new BehaviourSubject('initial value');

- компонент B:

<!-- template -->
{{ componentBinput }}

И

// typescript
@Input() componentBinput: string;

// if need you can affect its value to a new created subject
componentBinput$: BehaviourSubject<string> = new BehaviourSubject(this.componentBinput);

Вы можете сделать обмен данными другим способом, используя ту же стратегию, этоСтратегия - это лучшая практика, рекомендованная экспертами по угловым направлениям. Я ответил этим примером, потому что я считаю, что проблемы, возникающие при реализации вашей функции, связаны с обменом данными, а не с манипулированием наблюдаемыми объектами и напоминанием, что это очень плохая практика - вкладывать 2 подписки илииспользуйте подписки на файл TS, когда этого можно избежать, используя асинхронный канал в шаблоне.

0 голосов
/ 24 января 2019

Я не совсем уверен, как именно вы можете работать с Observable с двумя подписками.

Если вы хотите отойти от пользователя, используя router.navigate(...), и вы уже подписались на Observable в вашем классе TypeScript, почему бы не использовать ту же переменную в вашем шаблоне и удалить async канал из вашего шаблона.

Вот как это будет выглядеть в коде:

В вашемКласс компонента:

msg;

...

message$.subscribe(message => {
  if (!message) {
    this.router.navigate(...);
  } else {
    this.msg = message;
  }
});

И в вашем шаблоне:

<div *ngIf='msg'>
  ...
</div>
...