WatchRendition.ts
58 lines
| 1.7 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"; | ||||
import { place } from "dojo/dom-construct"; | ||||
import { getScope, render } from "./Renderer"; | ||||
import { RenditionBase } from "./RenditionBase"; | ||||
import { Scope } from "./Scope"; | ||||
import { locateNode } from "./traits"; | ||||
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(); | ||||
constructor(component: (arg: T) => any, subject: any) { | ||||
super(); | ||||
argumentNotNull(component, "component"); | ||||
this._factory = component; | ||||
this._node = document.createComment("WatchRendition placeholder"); | ||||
} | ||||
protected _create(attrs: object, children: any[]) { | ||||
const _attrs: any = attrs || {}; | ||||
const _children = children.map(x => this.getItemDom(x)); | ||||
this._node = this.getItemDom( | ||||
this._factory.call(null, { ..._attrs, children: _children }) | ||||
); | ||||
const scope = getScope(); | ||||
scope.own(this._scope); | ||||
// если отрендерили текст? или DocumentFragment | ||||
} | ||||
private async _render(value: T) { | ||||
const [refNode, position] = locateNode(this._node); | ||||
this._scope.clean(); | ||||
this._node = await render(() => this._factory(value), this._scope); | ||||
if (refNode) | ||||
place(this._node, refNode, position); | ||||
} | ||||
protected _getDomNode() { | ||||
if (!this._node) | ||||
throw new Error("The instance of the widget isn't created"); | ||||
return this._node; | ||||
} | ||||
} | ||||