##// END OF EJS Templates
fixed cyclic module references tsx/traits, tsx/FunctionRendition, tsx/RenditionBase
cin -
r89:367f8caa5bf8 v1.2.8 default
parent child
Show More
@@ -1,8 +1,11
1 import { Constructor } from "@implab/core-amd/interfaces";
1 import { Constructor, IDestroyable, IRemovable } from "@implab/core-amd/interfaces";
2 2 import { HtmlRendition } from "./tsx/HtmlRendition";
3 3 import { WidgetRendition } from "./tsx/WidgetRendition";
4 import { isWidgetConstructor, Rendition } from "./tsx/traits";
4 import { destroy, isWidgetConstructor, Rendition } from "./tsx/traits";
5 5 import { FunctionRendition } from "./tsx/FunctionRendition";
6 import Stateful = require("dojo/Stateful");
7 import _WidgetBase = require("dijit/_WidgetBase");
8 import { DjxWidgetBase } from "./tsx/DjxWidgetBase";
6 9
7 10 export function createElement<T extends Constructor | string | ((props: any) => Element)>(elementType: T, ...args: any[]): Rendition {
8 11 if (typeof elementType === "string") {
@@ -38,3 +41,79 export interface EventSelector {
38 41 }
39 42
40 43 export type DojoMouseEvent<T = any> = MouseEvent & EventSelector & EventDetails<T>;
44
45 type StatefulProps<T> = T extends Stateful<infer A> ? A : never;
46
47 type CleanFn = (instance: IRemovable | IDestroyable) => void;
48
49 /**
50 * Observers the property and calls render callback each change.
51 *
52 * @param target The target object which property will be observed.
53 * @param prop The name of the property.
54 * @param render The callback which will be called every time the value is changed
55 * @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
56 * @returns Rendition which is created instantly
57 */
58 export function watch<W extends _WidgetBase, K extends keyof W>(
59 target: W,
60 prop: K,
61 render: (model: W[K]) => any,
62 cleanupOrOwner?: { own: CleanFn } | CleanFn
63 ): Rendition;
64 /**
65 * Observers the property and calls render callback each change.
66 *
67 * @param target The target object which property will be observed.
68 * @param prop The name of the property.
69 * @param render The callback which will be called every time the value is changed
70 * @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
71 * @returns Rendition which is created instantly
72 */
73 export function watch<T extends Stateful, K extends keyof StatefulProps<T>>(
74 target: T,
75 prop: K,
76 render: (model: StatefulProps<T>[K]) => any,
77 cleanupOrOwner?: { own: CleanFn } | CleanFn
78 ): Rendition;
79 export function watch<T extends Stateful, K extends keyof StatefulProps<T> & string>(
80 target: T,
81 prop: K,
82 render: (model: StatefulProps<T>[K]) => any,
83 cleanupOrOwner: { own: CleanFn } | CleanFn = () => { }
84 ) {
85 let rendition = new FunctionRendition(() => render(target.get(prop)));
86 const _own = cleanupOrOwner instanceof Function ? cleanupOrOwner : (x: IRemovable) => cleanupOrOwner.own(x);
87 _own(target.watch(prop, (_name, oldValue, newValue) => {
88 if (oldValue !== newValue) {
89 const newRendition = new FunctionRendition(() => render(newValue));
90 newRendition.placeAt(rendition.getDomNode(), "replace");
91 destroy(rendition.getDomNode());
92 rendition = newRendition;
93 }
94 }));
95 return rendition;
96 }
97
98 /** Decorates the method which will be registered as the handle for the specified event.
99 * This decorator can be applied to DjxWidgetBase subclass methods.
100 *
101 * ```
102 * @on("click")
103 * _onClick(eventObj: MouseEvent) {
104 * // ...
105 * }
106 * ```
107 */
108 export const on = <E extends string>(...eventNames: E[]) =>
109 <K extends string,
110 T extends DjxWidgetBase<any, { [p in E]: EV }>,
111 EV extends Event
112 >(
113 target: T,
114 key: K,
115 _descriptor: TypedPropertyDescriptor<(eventObj: EV) => void> | TypedPropertyDescriptor<() => void>
116 ): any => {
117 const handlers = eventNames.map(eventName => ({ eventName, handlerMethod: key }))
118 target._eventHandlers = target._eventHandlers ? target._eventHandlers.concat(handlers) : handlers;
119 };
@@ -1,11 +1,8
1 import { IDestroyable, IRemovable } from "@implab/core-amd/interfaces";
1 import { IDestroyable } from "@implab/core-amd/interfaces";
2 2 import { isDestroyable } from "@implab/core-amd/safe";
3 3 import _WidgetBase = require("dijit/_WidgetBase");
4 4 import registry = require("dijit/registry");
5 5 import dom = require("dojo/dom-construct");
6 import Stateful = require("dojo/Stateful");
7 import { FunctionRendition } from "./FunctionRendition";
8 import { DjxWidgetBase } from "./DjxWidgetBase";
9 6
10 7 type _WidgetBaseConstructor = typeof _WidgetBase;
11 8
@@ -149,80 +146,3 export function startupWidgets(target: N
149 146 target.startup();
150 147 }
151 148 }
152
153
154 type StatefulProps<T> = T extends Stateful<infer A> ? A : never;
155
156 type CleanFn = (instance: IRemovable | IDestroyable) => void;
157
158 /**
159 * Observers the property and calls render callback each change.
160 *
161 * @param target The target object which property will be observed.
162 * @param prop The name of the property.
163 * @param render The callback which will be called every time the value is changed
164 * @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
165 * @returns Rendition which is created instantly
166 */
167 export function watch<W extends _WidgetBase, K extends keyof W>(
168 target: W,
169 prop: K,
170 render: (model: W[K]) => any,
171 cleanupOrOwner?: { own: CleanFn } | CleanFn
172 ): Rendition;
173 /**
174 * Observers the property and calls render callback each change.
175 *
176 * @param target The target object which property will be observed.
177 * @param prop The name of the property.
178 * @param render The callback which will be called every time the value is changed
179 * @param cleanupOrOwner The object with method `own` or an callback to register lifecycle for the observer.
180 * @returns Rendition which is created instantly
181 */
182 export function watch<T extends Stateful, K extends keyof StatefulProps<T>>(
183 target: T,
184 prop: K,
185 render: (model: StatefulProps<T>[K]) => any,
186 cleanupOrOwner?: { own: CleanFn } | CleanFn
187 ): Rendition;
188 export function watch<T extends Stateful, K extends keyof StatefulProps<T> & string>(
189 target: T,
190 prop: K,
191 render: (model: StatefulProps<T>[K]) => any,
192 cleanupOrOwner: { own: CleanFn } | CleanFn = () => { }
193 ) {
194 let rendition = new FunctionRendition(() => render(target.get(prop)));
195 const _own = cleanupOrOwner instanceof Function ? cleanupOrOwner : (x: IRemovable) => cleanupOrOwner.own(x);
196 _own(target.watch(prop, (_name, oldValue, newValue) => {
197 if (oldValue !== newValue) {
198 const newRendition = new FunctionRendition(() => render(newValue));
199 newRendition.placeAt(rendition.getDomNode(), "replace");
200 destroy(rendition.getDomNode());
201 rendition = newRendition;
202 }
203 }));
204 return rendition;
205 }
206
207 /** Decorates the method which will be registered as the handle for the specified event.
208 * This decorator can be applied to DjxWidgetBase subclass methods.
209 *
210 * ```
211 * @on("click")
212 * _onClick(eventObj: MouseEvent) {
213 * // ...
214 * }
215 * ```
216 */
217 export const on = <E extends string>(...eventNames: E[]) =>
218 <K extends string,
219 T extends DjxWidgetBase<any, { [p in E]: EV }>,
220 EV extends Event
221 >(
222 target: T,
223 key: K,
224 _descriptor: TypedPropertyDescriptor<(eventObj: EV) => void> | TypedPropertyDescriptor<() => void>
225 ): any => {
226 const handlers = eventNames.map(eventName => ({ eventName, handlerMethod: key }))
227 target._eventHandlers = target._eventHandlers ? target._eventHandlers.concat(handlers) : handlers;
228 };
@@ -1,8 +1,7
1 1 import { djbase, djclass, bind, prototype, AbstractConstructor } from "../declare";
2 2
3 3 import { DjxWidgetBase } from "../tsx/DjxWidgetBase";
4 import { createElement } from "../tsx";
5 import { on } from "../tsx/traits";
4 import { createElement, on } from "../tsx";
6 5
7 6 interface MyWidgetAttrs {
8 7 title: string;
General Comments 0
You need to be logged in to leave comments. Login now