4.5. 実装上の補足¶
4.5.1. エレメントのライフサイクル図¶
4.5.2. エレメントでのプロパティ操作¶
createElement や updateElement メソッドの中で、プロパティを操作したい場合があります。
プロパティから値を取得したい場合、以下のように実装します。
const uniquePropertyDefinition: PropertyDefinition & IUniquePropertyDefinition = {
stringProperty: {
displayName: 'stringProperty',
definition: {},
type: 'string',
value: 'string',
},
integerProperty: {
displayName: 'integerProperty',
definition: {},
type: 'integer',
value: 1,
},
decimalProperty: {
displayName: 'decimalProperty',
definition: {},
type: 'decimal',
value: 10,
},
booleanProperty: {
displayName: 'booleanProperty',
definition: {},
type: 'boolean',
value: true,
},
}
...
public updateElement(
builder: IHTMLElementBuilder,
container: IUIContainer,
properties: IUIElementPropertyAccessor<PropertyDefinition & ICommonPropertyDefinition>
): void {
// 文字列として取得する
const stringValue = properties.getProperty('stringProperty').toString();
// 数値として取得する
const integerValue = properties.getProperty('integerProperty').toNumber();
const decimalValue = properties.getProperty('decimalProperty').toNumber();
// 真偽値として取得する
const booleanValue = properties.getProperty('booleanProperty').toBoolean();
// null かどうかを判定する
const isNull = properties.getProperty('sampleProperty').isNull();
// 配列かどうかを判定する
const isArray = properties.getProperty('arrayProperty').isArray();
// オブジェクトかどうかを判定する
const isObject = properties.getProperty('objectProperty').isObject();
...
}
プロパティに値をセットしたい場合、以下のように実装します。
メソッドの第2引数にはプリミティブな値を指定します。
public updateElement(
builder: IHTMLElementBuilder,
container: IUIContainer,
properties: IUIElementPropertyAccessor<PropertyDefinition & ICommonPropertyDefinition>
): void {
// 文字列をセットする
properties.setProperty('stringProperty', 'foo', false);
// 数値をセットする
properties.setProperty('integerProperty', 1, false);
properties.setProperty('decimalProperty', 10, false);
// 真偽値をセットする
properties.setProperty('booleanProperty', true, false);
// null をセットする
properties.setProperty('sampleProperty', null, false);
// 配列をセットする
properties.setProperty('arrayProperty', ['foo', 'bar'], false);
// オブジェクトをセットする
properties.setProperty('objectProperty', {foo: 'bar'}, false);
...
}
public createElement(
container: IUIContainer,
properties: IUIElementPropertyAccessor<PropertyDefinition & ICommonPropertyDefinition>
): IHTMLElementBuilder {
const builder = window.imHichee.HTMLElementBuilder.createElement('input', HTMLInputElement);
const tag = builder.tag as HTMLInputElement;
// 自身のエレメントも含めて再レンダリングするときだけ第3引数に true を指定する
// 自身の updateElement が再度呼び出されるため、無限ループに注意する
tag.addEventListener('xxx', () => {
properties.setProperty('stringProperty', 'somevalue', true);
}
return builder;
}
4.5.3. アクションでのパラメータ操作¶
アクションアイテムを実行する際に、アクションアイテムのパラメータに設定された値を取得する場合は、parameters.getParameter を使用します。
変数の値を書き換えたい場合は、container.parameters.writeAs*** を使用します。
以下のように実装します。
public run(
context: IUIContainerActionContext,
container: IUIContainer,
component: IUIComponent,
parameters: IUIContainerActionParameterAccessor<ParameterDefinition>
) {
// 取得
// アクションダイアログの設定どおりに取得したい場合
const paramRaw = parameters.getParameter('param').toRaw(container);
// 変数の値を取得したい場合
const paramArgument = parameters.getParameter('param').toArgument(container);
...
// セット
// プリミティブな値をセットする場合
container.parameters.writeAsPrimitive(container, parameters.getParameter('param').toRaw(), paramPrimitive);
// Argument をセットする場合
container.parameters.writeAsArgument(container, parameters.getParameter('param').toRaw(), paramArgument);
// 配列を考慮してセットする場合
// 変数のパラメータが配列の場合、自動的に要素数1の ArrayArgument に変換されます。
// 変数のパラメータが配列でなく、かつ value に配列が指定された場合、最初の要素に対して Argument に変換されます。
container.parameters.writeAsPrimitiveStrictArrayTyped(container, parameters.getParameter('param').toRaw(), param);
...
}
4.5.4. Argument の生成方法¶
window.imHichee.ArgumentFactory を使用してください。
作成する Argument の型に合わせ、以下のメソッドを利用してください。
- createAsArray: (container: IUIContainer, raw: IArgument[]) => IArrayArgument;
- ArrayArgument を作成
- createAsBoolean: (container: IUIContainer, raw: boolean) => IArgument;
- BooleanArgument を作成
- createAsDate: (container: IUIContainer, raw: string | number | {date: Date; offset?: number}) => IDateArgument;
- DateArgument を作成
- createAsDouble: (container: IUIContainer, raw: number) => INumberArgument;
- DoubleArgument を作成
- createAsEmptyObject: (container: IUIContainer) => IObjectArgument;
- 空の ObjectArgument を作成
- createAsFraction: (container: IUIContainer, raw: IFraction) => INumberArgument;
- FractionArgument を作成
- createAsInteger: (container: IUIContainer, raw: number) => INumberArgument;
- IntegerArgument を作成
- createAsNull: (container: IUIContainer) => IArgument;
- NullArgument を作成
- createAsObject: (container: IUIContainer, raw: IKeyValueMap<string, IArgument>) => IObjectArgument;
- ObjectArgument を作成
- 引数の raw には new window.imHichee.KeyValueMap<string, IArgument>() で作成したインスタンスを指定してください。
- createAsParameterPath: (container: IUIContainer, target: IUIComponent, raw: string) => IParameterPathArgument;
- ParameterPathArgument を作成
- createAsString: (container: IUIContainer, raw: string) => IArgument;
- StringArgument を作成
使用例は以下のとおりです。
const ArgumentFactory = window.imHichee.ArgumentFactory;
const KeyValueMap = window.imHichee.KeyValueMap;
// StringArgument を作成する
const stringArgument = ArgumentFactory.createAsString(container, 'foo');
// ObjectArgument の中身を作成する
const obj = new KeyValueMap<string, IArgument>();
obj.put('key1', ArgumentFactory.createAsInteger(container, 1));
obj.put('key2', ArgumentFactory.createAsInteger(container, 2));
// ObjectArgument を作成する
const objectArgument = ArgumentFactory.createAsObject(container, obj);
4.5.5. プロパティのイベントに指定されているイベントタイプ¶
プロパティの「イベント」で指定されるアクションが、どの DOM イベントを利用しているかを列挙します。
onMouseDown 以下はプロパティには表示されませんが、エレメントを作成する際に利用可能なイベントです。
イベントに指定されたアクションは createElement と updateElement の間に DOM にバインドされます。
イベント | イベントタイプ |
---|---|
クリック時 | click |
ダブルクリック時 | dblclick |
キー押下時 | keydown |
フォーカスイン | focus |
フォーカスアウト | blur |
入力値変更時 | change |
入力値変更中 | input |
onMouseDown | mousedown |
onMouseMove | mousemove |
onMouseEnter | mouseenter |
onMouseLeave | mouseleave |
onMouseOut | mouseout |
onMouseOver | mouseover |
onMouseUp | mouseup |
onKeyPress | keypress |
onKeyUp | keyup |
// 例:フォーカスアウト時に、プロパティで指定されたアクションの前に処理を行う
public createElement(
container: IUIContainer,
properties: IUIElementPropertyAccessor<PropertyDefinition & ICommonPropertyDefinition>
): IHTMLElementBuilder {
const builder = window.imHichee.HTMLElementBuilder.createElement('input', HTMLInputElement);
const tag = builder.tag as HTMLInputElement;
// 上記のフォーカスアウトに相当するイベントタイプ blur を指定する
tag.addEventListener('blur', () => {
// 処理
}
return builder;
}
4.5.6. エレメントのインスタンスを作成¶
エレメントのインスタンスを作成する場合は、コンテナからエレメントコントローラを取得し、コントローラにインスタンスの作成を依頼します。
以下のように実装します。
// 例:自身エレメントの子として、いくつかのエレメントを作成する
public createChildren(
self: IUIElement,
container: IUIContainer,
properties: IUIElementPropertyAccessor<PropertyDefinition & ICommonPropertyDefinition>
): IUIElement[] {
return [
// クラスを直接指定する場合
container.controller.createInstanceByClass(MyZipCodeField, self),
// クラス名(文字列)を指定する場合
container.controller.createInstanceByTypeName('MyZipCodeField', self)
];
}
4.5.7. 親エレメントの取得¶
親エレメントを取得する場合は、element.parent プロパティから取得します。
以下のように実装します。
// 例:フォーカスアウト時に、self から親エレメントを取得する
public createChildren(
self: IUIElement,
container: IUIContainer,
properties: IUIElementPropertyAccessor<PropertyDefinition & ICommonPropertyDefinition>
): IUIElement[] {
const tag = self.builder.tag;
// 上記のフォーカスアウトに相当するイベントタイプ blur を指定する
tag.addEventListener('blur', () => {
// 最新の親を取得する場合は self.parent から取得する
const parent = self.parent;
// parent はエレメントまたはコンテナ。 parent.clazz で判別可能
if (parent.clazz === 'UIContainer') {
// コンテナの場合
} else if (parent.clazz === 'UIElement') {
// エレメントの場合
}
...
}
...
}
4.5.8. 子エレメントの取得¶
子エレメントを取得する場合は、element.children プロパティから取得します。
ただし、children プロパティから取得した子エレメントは、順序が保証されていません。
画面上で配置されている順序通りに取得したい場合は、コンテナからエレメントコントローラを取得し、コントローラから並び替え済みの子エレメント一覧を取得します。
以下のように実装します。
// 例:フォーカスアウト時に、self から子エレメントを取得する
public createChildren(
self: IUIElement,
container: IUIContainer,
properties: IUIElementPropertyAccessor<PropertyDefinition & ICommonPropertyDefinition>
): IUIElement[] {
const tag = self.builder.tag;
// 上記のフォーカスアウトに相当するイベントタイプ blur を指定する
tag.addEventListener('blur', () => {
// 最新の子エレメントを取得する場合は、self.children から取得する
// ただし、これは順不同であり、必ずしも配置順ではないことに注意する
const children = self.children;
// 配置順で子エレメントを取得する場合は、container 経由で取得する
// ただし、並び替えを行うため、パフォーマンスが悪化するので、順序が重要な場合にのみ使用する
const sortedChildren = container.controller.getSortedChildren(self);
...
}
...
}