|
|
import { id as mid } from "module";
|
|
|
import { TraceSource } from "@implab/core-amd/log/TraceSource";
|
|
|
import { argumentNotNull } from "@implab/core-amd/safe";
|
|
|
import { render } from "./Renderer";
|
|
|
import { RenditionBase } from "./RenditionBase";
|
|
|
import { IScope, Scope } from "./Scope";
|
|
|
import { Observable } from "../observable";
|
|
|
|
|
|
const trace = TraceSource.get(mid);
|
|
|
|
|
|
export class WatchRendition<T> extends RenditionBase<Node> {
|
|
|
private readonly _factory: (arg: T) => any;
|
|
|
|
|
|
private _node: Node;
|
|
|
|
|
|
private readonly _scope = new Scope();
|
|
|
|
|
|
private readonly _subject: Observable<T>;
|
|
|
|
|
|
constructor(component: (arg: T) => any, subject: Observable<T>) {
|
|
|
super();
|
|
|
argumentNotNull(component, "component");
|
|
|
|
|
|
this._factory = component;
|
|
|
|
|
|
this._subject = subject;
|
|
|
|
|
|
this._node = document.createComment("WatchRendition placeholder");
|
|
|
}
|
|
|
|
|
|
protected _create(attrs: object, children: any[], scope: IScope) {
|
|
|
scope.own(this._scope);
|
|
|
scope.own(this._subject.on({ next: this._onValue }))
|
|
|
}
|
|
|
|
|
|
private _onValue = (value: T) => void this._render(value).catch( e => trace.error(e));
|
|
|
|
|
|
private async _render(value: T) {
|
|
|
const prevNode = this._node;
|
|
|
this._scope.clean();
|
|
|
|
|
|
this._node = await render(() => this._factory(value), this._scope);
|
|
|
|
|
|
this.placeAt(prevNode, "replace");
|
|
|
}
|
|
|
|
|
|
protected _getDomNode() {
|
|
|
if (!this._node)
|
|
|
throw new Error("The instance of the widget isn't created");
|
|
|
return this._node;
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|