是否可以在组件文件中重新创建ngIf和异步管道行为?

时间:2019-01-24 13:29:51

标签: javascript angular rxjs observable

我确实有两个组件,一个表单组件和一个谢谢页面。(完整的代码清单在这里:What is the proper way to share data between two components using rxjs ReplaySubject?

我正在使用ngIf和异步管道处理可观察对象,如下所示:

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

这是一个谢谢页面模板,可以正常工作。

我现在想要实现的是:如果用户到达“谢谢”页面,则message $不会有任何值,那么我想将用户重定向到表单内容。 我正在尝试重现组件中的模板行为(无message $,不显示任何内容),因此可以使用router.navigate()将用户重定向到表单组件。

任何帮助将不胜感激,在此先感谢您!

注意:我要订阅相同的可观察项两次,一个订阅将由异步管道处理,另一订阅应由组件处理。有更有效的方法吗?

3 个答案:

答案 0 :(得分:1)

我认为您不应该在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');

-componentB:

<!-- 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文件使用订阅是非常不好的做法。

答案 1 :(得分:0)

我不太确定一次订阅两次即可使用Observable的能力如何。

如果您想使用router.navigate(...)来引导用户,并且已经在TypeScript类中订阅了Observable,为什么不在模板中使用相同的变量并删除{{1} }模板中的管道。

这就是代码中的样子:

在您的组件类中:

async

在您的模板中:

msg;

...

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

答案 2 :(得分:-1)

我使用的是ReplaySubject而不是BehaviorSubject。那是不对的。最后,我省略了最重要的部分。 BehaviorSubject对于检查值随时间的变化情况很有用。

我切换到BehaviorSubject,是因为它将始终在订阅时发出最后一个值,因此,无需添加任何额外的逻辑或发出任何额外的值,也无需检查可观察对象是否为“空”。 >