import { Observable, BehaviorSubject } from 'rxjs'; import { TemplateRef, ViewContainerRef, EventEmitter, OnInit } from '@angular/core'; import { Destroyable } from '../../destroyable/destroyable'; import { ResolvedObserveContext } from './types/general'; import * as i0 from "@angular/core"; /** * The base class for all `*observeXXX` directives. * This directive bind an observable or a collection of observables with a template, causing the values in the template to be updated whenever the observables emit. * * Any template assigned with the directive will render immediately, and its view context will be updated with the emitted value on * each emission. The directive will be responsible for subscribing on init and unsubscribing on destroy. * * ## Features * * #### Shared observable * The watched observable will automatically be multicasted so that any child observables created by the template will use the same * stream. * * The shared observable can be accessed using the `let source = source` microsyntax. * * #### Observer events * Whenever the observable changes state or emits a value, the corresponding event is emitted: * `nextCalled` - A value has been emitted. `$event` will be the emitted value. * `errorCalled` - An error has occured in the pipeline. `$event` will be the error. * `completeCalled` - The observable has completed. `$event` will be void. * * > Because of limitations to Angular's Structural Directives, in order to bind the events the desugared syntax must be used. * This, for example, **will trigger** the event: * > ```html * > * > ... * > * > ``` * > * >This **will NOT trigger** the event: * >```html * >
...
* >``` * * ## ⚠️ Extending notes: * As the base class cannot deduce the directive selector (e.g. `observeLatest`, `observeMerge`, etc.) the extending class * is required to do 4 things: * 1. Implement the abstract `selector` member and assign it with the directive's selector. * 2. Implement and `@Input() public set (value: T)` which will pass its value to the `input` member. * 3. Implement a static context TypeGuard. * * These will enable Angular features like template type checking and the microsyntax `as` keyword. * * @export * @abstract * @class ObserveBaseDirective * @extends {Destroyable} * @implements {OnInit} * @template TInput The type of value this directive will work with. Depends on the extending class. * @template TResolved The type of value emitted by the observable. Depends on the extending class. * @template TContext The type of the context object the template will work with. */ export declare abstract class ObserveBaseDirective> extends Destroyable implements OnInit { private readonly template; private readonly viewContainer; /** * Triggered whenever the observable emits a value. `$event` will be the emitted value. * * @type {EventEmitter} */ nextCalled: EventEmitter; /** * Triggered when an error occurs in the observable's pipeline. `$event` will be the error. * * @type {EventEmitter} */ errorCalled: EventEmitter; /** * Triggered when the observable completes. `$event` will be the void. * * @type {EventEmitter} */ completeCalled: EventEmitter; private view; /** * The selector defined for the directive extending this class. Will be used to create a corresponding * property in the view context in order to make the micro-syntax `as` keyword work. * * @protected * @abstract * @type {string} */ protected abstract readonly selector: string; /** * ### Why BehaviorSubject<{@link TInput s} | null> and not Subject<{@link TInput}> * `input` is set from @Input properties. For some reason, Angular passes-in the first value BEFORE * ngOnInit, even though other @Input properties (e.g. showAfter, showFor) are passed AFTER ngOnInit. * If subscription occurs in the constructor, `input` will emit the first observable too fast, which * might lead to pipes breaking or misbehaving if they rely on properties to be instantiated first. * * This leads to subscribing in ngOnInit, to allow Angular time to initialize those. * BUT, if `input` is a Subject, as the first value was already emitted BEFORE ngOnInit, it will not be * captured by our subscription to `input`. Hence the BehaviorSubject - To allow capturing that first observable. */ protected readonly input: BehaviorSubject; constructor(template: TemplateRef, viewContainer: ViewContainerRef); ngOnInit(): void; /** * Takes the input passed to the directive (which might be an observable, a map or an array of observable for example) * and creates an observable that combines and represents all the observables in the value. * * Intended for applying functions like `combineLatest()`, `contact()`, etc. * * @protected * @abstract * @param {TInput} input The input passed to the directive (which might be an observable, a map or an array of observable for example). * @return {Observable} An observable which combines and represents all the observables in the input value. */ protected abstract observeInput(input: TInput): Observable; private contextFeed; private onStateChange; private renderView; private updateViewContext; protected createViewContext({ value, source }: { value?: TResolved | null; source?: Observable; }): TContext; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵdir: i0.ɵɵDirectiveDeclaration, never, never, {}, { "nextCalled": "nextCalled"; "errorCalled": "errorCalled"; "completeCalled": "completeCalled"; }, never, never, false>; }