WatchRendition.ts
56 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
|
r96 | import { render } from "./Renderer"; | ||
cin
|
r94 | import { RenditionBase } from "./RenditionBase"; | ||
cin
|
r96 | import { IScope, Scope } from "./Scope"; | ||
import { Observable } from "../observable"; | ||||
cin
|
r94 | |||
const trace = TraceSource.get(mid); | ||||
cin
|
r97 | const noop = () => {}; | ||
cin
|
r94 | export class WatchRendition<T> extends RenditionBase<Node> { | ||
private readonly _factory: (arg: T) => any; | ||||
private _node: Node; | ||||
private readonly _scope = new Scope(); | ||||
cin
|
r96 | private readonly _subject: Observable<T>; | ||
constructor(component: (arg: T) => any, subject: Observable<T>) { | ||||
cin
|
r94 | super(); | ||
argumentNotNull(component, "component"); | ||||
this._factory = component; | ||||
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
|
r96 | private _onValue = (value: T) => void this._render(value).catch( e => trace.error(e)); | ||
cin
|
r94 | private async _render(value: T) { | ||
cin
|
r96 | const prevNode = this._node; | ||
cin
|
r94 | this._scope.clean(); | ||
this._node = await render(() => this._factory(value), this._scope); | ||||
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; | ||||
} | ||||
} | ||||