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);
        ...
    }
    ...
}