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