@Input绑定可以成为Angular中的可观察对象吗?

时间:2017-07-08 01:11:07

标签: angular rxjs observable

我正在创建一个在输入字段下显示验证错误的组件。如果显示错误消息,并且用户提交了表单我想要闪烁消息以引起他们的注意。

我想知道是否可以使用observable作为输入绑定?

这样我就可以在观察到任何数据时订阅输入和闪存。

以下是我的想法的一个例子:

@Component({..})
export class MessageComponent implement OnChanges {
   @Input()
   public flash: Observable<any>;

    public ngOnChanges(changes: SimpleChanges): void {
        if ('flash' in changes) {
            (<Observable<any>> changes['flash'].currentValue).subscribe(() => {
                // trigger the flash animation here
            });
        }
    }
}

我能弄清楚的是,这是否会泄漏内存,以及我何时/何时取消订阅(或者甚至是必要的)。

Angular允许这种做法吗?

2 个答案:

答案 0 :(得分:6)

是的,您可以使用observable作为输入。

您是否需要取消订阅取决于所讨论的观察结果。当观察完成或出现错误时,任何订阅者都会自动取消订阅。所以,一般来说,如果你知道一个observable完成了,那么就不需要显式的取消订阅。

然而,看看你的代码片段,这似乎是次要问题,因为你编写的代码表明你希望输入能够改变。

在这种情况下,您应该在发生更改时取消订阅。否则,您将拥有两个订阅者 - 第一个仍然可以收听原始flash可观察对象。

import { Subscription } from 'rxjs/Subscription';

@Component({..})
export class MessageComponent implement OnChanges, OnDestroy {

    @Input()
    public flash: Observable<any>;
    private flashSubscription: Subscription;

    public ngOnChanges(changes: SimpleChanges): void {
        if ('flash' in changes) {
            if (this.flashSubscription) {
                this.flashSubscription.unsubscribe();
            }
            this.flashSubscription = (<Observable<any>> changes['flash'].currentValue).subscribe(() => {
                // trigger the flash animation here
            });
        }
    }

    public ngOnDestroy(): void {
        if (this.flashSubscription) {
            this.flashSubscription.unsubscribe();
        }
    }

我还会在unsubscribe中调用ngOnDestroy - 以便对未完成或错误的flash个可观察对象进行取消订阅。

请注意,多次调用订阅的unsubscribe方法是安全的。

答案 1 :(得分:0)

如果消息的来源是可观察的,那么使用异步管道可能会更好。

ngOnChanges

这将为您处理有关清理的订阅。

然后,因为您已经在使用message-仅在发生更改时才触发-因此您只需在public ngOnChanges(changes: SimpleChanges): void { if ('message' in changes) { // trigger the flash animation here } } 发生更改时才触发动画。

:enter

对于所示的示例,无需让您的消息控件订阅事物并期望可观察到的输入。

或者,您可以使用动画和 <path d="M50 50 L50 0 A1 1 0 0 1 100 50 Z" fill="red" opacity="0.7"></path> <path d="M0 50 A1 1 0 0 1 100 50 Z" fill="blue"></path> <path d="M0 50 A1 1 0 0 1 50 0 Z" fill="purple" opacity="0.7"></path> <path d="M50 0 A50 50 0 0 0 0 50 Z" fill="green"></path> 事件在第一次显示消息时显示动画。每次闪烁都会令人讨厌。

如果您真的很想使用某种外部触发器来引起闪烁(并且我意识到您可能简化了您的示例),则可以调查使用伪指令来执行此操作,以便以后可以重用。 (然后,您可能需要使用AnimationBuilder)。这是一条更复杂的路线。