UNPKG

@bespunky/angular-zen

Version:

The Angular tools you always wished were there.

83 lines 11 kB
import { combineLatest } from 'rxjs'; import { Directive, Input } from '@angular/core'; import { ObserveMapDirective } from '../abstraction/observe-map-base.directive'; import * as i0 from "@angular/core"; /** * Documentation in {@link ObserveLatestDirective.observeLatest} to allow in-template tooltips. * @export * @class ObserveLatestDirective * @extends {ObserveMapDirective<T, ObserveLatestContext<T>>} * @template T The type of observables map received by the directive. */ export class ObserveLatestDirective extends ObserveMapDirective { constructor() { super(...arguments); // Seems like for template typechecking to work with a generic type holding `unknown`, the generic type must be flattened // and not represented by a new type. When I tried creating an ObservableMap = { ...key: Observable<unknown> } and use it // as T extends ObservableMap, the type system failed to infer the inner types of the observables. // T extends { ...key: Observable<unknown> } works fine. this.selector = 'observeLatest'; } /** * Combines a map of observables using rxjs {@link https://rxjs.dev/api/index/function/combineLatest combineLatest()} and exposes the emitted values to the template. * Values are exposed in a map which keys are the same keys as the original observable map and values are * the emitted values corresponding to those keys. * * Emitted values will be available as the implicit context values but will also be spread into the context by key. * Meaning, this would work: * ```html * <div *observeLatest="{ x: x$, y: y$ } as result">{{result.x}}</div> * ``` * * And this also: * ``` * <div *observeLatest="{ x: x$, y: y$ }; let x = x">{{x}}</div> * ``` * * 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 * ><ng-template [observe]="x$" let-source="source" (nextCalled)="onNext($event)"> * > ... * ></ng-template> * > ``` * > * >This **will NOT trigger** the event: * >```html * > <div *observe="x$; let source = source" (nextCalled)="onNext($event)">...</div> * >``` */ set observeLatest(value) { this.input.next(value); } static ngTemplateContextGuard(directive, context) { return true; } observeInput(input) { return combineLatest(input); } } ObserveLatestDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ObserveLatestDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); ObserveLatestDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: ObserveLatestDirective, selector: "[observeLatest]", inputs: { observeLatest: "observeLatest" }, usesInheritance: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: ObserveLatestDirective, decorators: [{ type: Directive, args: [{ selector: '[observeLatest]' }] }], propDecorators: { observeLatest: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JzZXJ2ZS1sYXRlc3QuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9hbmd1bGFyLXplbi9jb3JlL3NyYy9yeGpzL29ic2VydmUvZGlyZWN0aXZlcy9vYnNlcnZlLWxhdGVzdC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFjLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRCxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBVyxNQUFNLGVBQWUsQ0FBQztBQUUxRCxPQUFPLEVBQUUsbUJBQW1CLEVBQTZCLE1BQU0sMkNBQTJDLENBQUM7O0FBTzNHOzs7Ozs7R0FNRztBQUlILE1BQU0sT0FBTyxzQkFDUixTQUFRLG1CQUErQztJQUo1RDs7UUFNSSx5SEFBeUg7UUFDekgseUhBQXlIO1FBQ3pILGtHQUFrRztRQUNsRyx3REFBd0Q7UUFFOUMsYUFBUSxHQUFHLGVBQWUsQ0FBQztLQXdEeEM7SUF0REc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQTZDRztJQUNILElBQW9CLGFBQWEsQ0FBQyxLQUFRLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXZFLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBbUQsU0FBb0MsRUFBRSxPQUFnQixJQUF3QyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7SUFFbEwsWUFBWSxDQUFDLEtBQVE7UUFFM0IsT0FBTyxhQUFhLENBQUMsS0FBSyxDQUFnQyxDQUFDO0lBQy9ELENBQUM7O29IQS9EUSxzQkFBc0I7d0dBQXRCLHNCQUFzQjs0RkFBdEIsc0JBQXNCO2tCQUhsQyxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSxpQkFBaUI7aUJBQzlCOzhCQXlEdUIsYUFBYTtzQkFBaEMsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9ic2VydmFibGUsIGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERpcmVjdGl2ZSwgSW5wdXQgICAgICAgICAgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgT2JzZXJ2ZU1hcERpcmVjdGl2ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGZyb20gJy4uL2Fic3RyYWN0aW9uL29ic2VydmUtbWFwLWJhc2UuZGlyZWN0aXZlJztcbmltcG9ydCB7IE9ic2VydmVNYXBDb250ZXh0LCBFbWl0dGVkTWFwT2YsIE9ic2VydmFibGVNYXAgfSBmcm9tICcuLi9hYnN0cmFjdGlvbi90eXBlcy9tYXBzJztcblxudHlwZSBPYnNlcnZlTGF0ZXN0Q29udGV4dDxUIGV4dGVuZHMgT2JzZXJ2YWJsZU1hcD4gPSBPYnNlcnZlTWFwQ29udGV4dDxUPiAmIHtcbiAgICBvYnNlcnZlTGF0ZXN0OiBFbWl0dGVkTWFwT2Y8VD5cbn07XG5cbi8qKlxuICogRG9jdW1lbnRhdGlvbiBpbiB7QGxpbmsgT2JzZXJ2ZUxhdGVzdERpcmVjdGl2ZS5vYnNlcnZlTGF0ZXN0fSB0byBhbGxvdyBpbi10ZW1wbGF0ZSB0b29sdGlwcy5cbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBPYnNlcnZlTGF0ZXN0RGlyZWN0aXZlXG4gKiBAZXh0ZW5kcyB7T2JzZXJ2ZU1hcERpcmVjdGl2ZTxULCBPYnNlcnZlTGF0ZXN0Q29udGV4dDxUPj59XG4gKiBAdGVtcGxhdGUgVCBUaGUgdHlwZSBvZiBvYnNlcnZhYmxlcyBtYXAgcmVjZWl2ZWQgYnkgdGhlIGRpcmVjdGl2ZS5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbb2JzZXJ2ZUxhdGVzdF0nXG59KVxuZXhwb3J0IGNsYXNzIE9ic2VydmVMYXRlc3REaXJlY3RpdmU8VCBleHRlbmRzIHsgW2tleTogc3RyaW5nXTogT2JzZXJ2YWJsZTx1bmtub3duPiB9PlxuICAgICBleHRlbmRzIE9ic2VydmVNYXBEaXJlY3RpdmU8VCwgT2JzZXJ2ZUxhdGVzdENvbnRleHQ8VD4+XG57XG4gICAgLy8gU2VlbXMgbGlrZSBmb3IgdGVtcGxhdGUgdHlwZWNoZWNraW5nIHRvIHdvcmsgd2l0aCBhIGdlbmVyaWMgdHlwZSBob2xkaW5nIGB1bmtub3duYCwgdGhlIGdlbmVyaWMgdHlwZSBtdXN0IGJlIGZsYXR0ZW5lZFxuICAgIC8vIGFuZCBub3QgcmVwcmVzZW50ZWQgYnkgYSBuZXcgdHlwZS4gV2hlbiBJIHRyaWVkIGNyZWF0aW5nIGFuIE9ic2VydmFibGVNYXAgPSB7IC4uLmtleTogT2JzZXJ2YWJsZTx1bmtub3duPiB9IGFuZCB1c2UgaXRcbiAgICAvLyBhcyBUIGV4dGVuZHMgT2JzZXJ2YWJsZU1hcCwgdGhlIHR5cGUgc3lzdGVtIGZhaWxlZCB0byBpbmZlciB0aGUgaW5uZXIgdHlwZXMgb2YgdGhlIG9ic2VydmFibGVzLlxuICAgIC8vIFQgZXh0ZW5kcyB7IC4uLmtleTogT2JzZXJ2YWJsZTx1bmtub3duPiB9IHdvcmtzIGZpbmUuXG5cbiAgICBwcm90ZWN0ZWQgc2VsZWN0b3IgPSAnb2JzZXJ2ZUxhdGVzdCc7XG5cbiAgICAvKipcbiAgICAgKiBDb21iaW5lcyBhIG1hcCBvZiBvYnNlcnZhYmxlcyB1c2luZyByeGpzIHtAbGluayBodHRwczovL3J4anMuZGV2L2FwaS9pbmRleC9mdW5jdGlvbi9jb21iaW5lTGF0ZXN0IGNvbWJpbmVMYXRlc3QoKX0gYW5kIGV4cG9zZXMgdGhlIGVtaXR0ZWQgdmFsdWVzIHRvIHRoZSB0ZW1wbGF0ZS5cbiAgICAgKiBWYWx1ZXMgYXJlIGV4cG9zZWQgaW4gYSBtYXAgd2hpY2gga2V5cyBhcmUgdGhlIHNhbWUga2V5cyBhcyB0aGUgb3JpZ2luYWwgb2JzZXJ2YWJsZSBtYXAgYW5kIHZhbHVlcyBhcmVcbiAgICAgKiB0aGUgZW1pdHRlZCB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byB0aG9zZSBrZXlzLlxuICAgICAqIFxuICAgICAqIEVtaXR0ZWQgdmFsdWVzIHdpbGwgYmUgYXZhaWxhYmxlIGFzIHRoZSBpbXBsaWNpdCBjb250ZXh0IHZhbHVlcyBidXQgd2lsbCBhbHNvIGJlIHNwcmVhZCBpbnRvIHRoZSBjb250ZXh0IGJ5IGtleS5cbiAgICAgKiBNZWFuaW5nLCB0aGlzIHdvdWxkIHdvcms6XG4gICAgICogYGBgaHRtbFxuICAgICAqIDxkaXYgKm9ic2VydmVMYXRlc3Q9XCJ7IHg6IHgkLCB5OiB5JCB9IGFzIHJlc3VsdFwiPnt7cmVzdWx0Lnh9fTwvZGl2PlxuICAgICAqIGBgYFxuICAgICAqIFxuICAgICAqIEFuZCB0aGlzIGFsc286XG4gICAgICogYGBgXG4gICAgICogPGRpdiAqb2JzZXJ2ZUxhdGVzdD1cInsgeDogeCQsIHk6IHkkIH07IGxldCB4ID0geFwiPnt7eH19PC9kaXY+XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBBbnkgdGVtcGxhdGUgYXNzaWduZWQgd2l0aCB0aGUgZGlyZWN0aXZlIHdpbGwgcmVuZGVyIGltbWVkaWF0ZWx5LCBhbmQgaXRzIHZpZXcgY29udGV4dCB3aWxsIGJlIHVwZGF0ZWQgd2l0aCB0aGUgZW1pdHRlZCB2YWx1ZSBvblxuICAgICAqIGVhY2ggZW1pc3Npb24uIFRoZSBkaXJlY3RpdmUgd2lsbCBiZSByZXNwb25zaWJsZSBmb3Igc3Vic2NyaWJpbmcgb24gaW5pdCBhbmQgdW5zdWJzY3JpYmluZyBvbiBkZXN0cm95LlxuICAgICAqIFxuICAgICAqICMjIEZlYXR1cmVzXG4gICAgICogXG4gICAgICogIyMjIyBTaGFyZWQgb2JzZXJ2YWJsZVxuICAgICAqIFRoZSB3YXRjaGVkIG9ic2VydmFibGUgd2lsbCBhdXRvbWF0aWNhbGx5IGJlIG11bHRpY2FzdGVkIHNvIHRoYXQgYW55IGNoaWxkIG9ic2VydmFibGVzIGNyZWF0ZWQgYnkgdGhlIHRlbXBsYXRlIHdpbGwgdXNlIHRoZSBzYW1lXG4gICAgICogc3RyZWFtLlxuICAgICAqIFxuICAgICAqIFRoZSBzaGFyZWQgb2JzZXJ2YWJsZSBjYW4gYmUgYWNjZXNzZWQgdXNpbmcgdGhlIGBsZXQgc291cmNlID0gc291cmNlYCBtaWNyb3N5bnRheC5cbiAgICAgKiBcbiAgICAgKiAjIyMjIE9ic2VydmVyIGV2ZW50c1xuICAgICAqIFdoZW5ldmVyIHRoZSBvYnNlcnZhYmxlIGNoYW5nZXMgc3RhdGUgb3IgZW1pdHMgYSB2YWx1ZSwgdGhlIGNvcnJlc3BvbmRpbmcgZXZlbnQgaXMgZW1pdHRlZDogIFxuICAgICAqIGBuZXh0Q2FsbGVkYCAtIEEgdmFsdWUgaGFzIGJlZW4gZW1pdHRlZC4gYCRldmVudGAgd2lsbCBiZSB0aGUgZW1pdHRlZCB2YWx1ZS4gIFxuICAgICAqIGBlcnJvckNhbGxlZGAgLSBBbiBlcnJvciBoYXMgb2NjdXJlZCBpbiB0aGUgcGlwZWxpbmUuIGAkZXZlbnRgIHdpbGwgYmUgdGhlIGVycm9yLiAgXG4gICAgICogYGNvbXBsZXRlQ2FsbGVkYCAtIFRoZSBvYnNlcnZhYmxlIGhhcyBjb21wbGV0ZWQuIGAkZXZlbnRgIHdpbGwgYmUgdm9pZC5cbiAgICAgKlxuICAgICAqID4gQmVjYXVzZSBvZiBsaW1pdGF0aW9ucyB0byBBbmd1bGFyJ3MgU3RydWN0dXJhbCBEaXJlY3RpdmVzLCBpbiBvcmRlciB0byBiaW5kIHRoZSBldmVudHMgdGhlIGRlc3VnYXJlZCBzeW50YXggbXVzdCBiZSB1c2VkLlxuICAgICAqIFRoaXMsIGZvciBleGFtcGxlLCAqKndpbGwgdHJpZ2dlcioqIHRoZSBldmVudDpcbiAgICAgKiA+IGBgYGh0bWxcbiAgICAgKiA+PG5nLXRlbXBsYXRlIFtvYnNlcnZlXT1cIngkXCIgbGV0LXNvdXJjZT1cInNvdXJjZVwiIChuZXh0Q2FsbGVkKT1cIm9uTmV4dCgkZXZlbnQpXCI+XG4gICAgICogPiAgICAuLi5cbiAgICAgKiA+PC9uZy10ZW1wbGF0ZT5cbiAgICAgKiA+IGBgYFxuICAgICAqID5cbiAgICAgKiA+VGhpcyAqKndpbGwgTk9UIHRyaWdnZXIqKiB0aGUgZXZlbnQ6XG4gICAgICogPmBgYGh0bWxcbiAgICAgKiA+IDxkaXYgKm9ic2VydmU9XCJ4JDsgbGV0IHNvdXJjZSA9IHNvdXJjZVwiIChuZXh0Q2FsbGVkKT1cIm9uTmV4dCgkZXZlbnQpXCI+Li4uPC9kaXY+XG4gICAgICogPmBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzZXQgb2JzZXJ2ZUxhdGVzdCh2YWx1ZTogVCkgeyB0aGlzLmlucHV0Lm5leHQodmFsdWUpOyB9XG4gICAgXG4gICAgc3RhdGljIG5nVGVtcGxhdGVDb250ZXh0R3VhcmQ8VCBleHRlbmRzIHsgW2tleTogc3RyaW5nXTogT2JzZXJ2YWJsZTx1bmtub3duPiB9PihkaXJlY3RpdmU6IE9ic2VydmVMYXRlc3REaXJlY3RpdmU8VD4sIGNvbnRleHQ6IHVua25vd24pOiBjb250ZXh0IGlzIE9ic2VydmVMYXRlc3RDb250ZXh0PFQ+IHsgcmV0dXJuIHRydWU7IH1cbiAgICBcbiAgICBwcm90ZWN0ZWQgb2JzZXJ2ZUlucHV0KGlucHV0OiBUKTogT2JzZXJ2YWJsZTxFbWl0dGVkTWFwT2Y8VD4+XG4gICAge1xuICAgICAgICByZXR1cm4gY29tYmluZUxhdGVzdChpbnB1dCkgYXMgT2JzZXJ2YWJsZTxFbWl0dGVkTWFwT2Y8VD4+O1xuICAgIH1cbn1cbiJdfQ==