開発者ブログ
リファレンス(仕様詳細) » ディスクリプタの仕様

ディスクリプタの仕様

Last modified by fukudayasuo on 2014/11/10, 16:18

データモデルを作成する時に指定するオブジェクトをディスクリプタと言います。このページではディスクリプタオブジェクトの記述仕様を説明します。

ディスクリプタ

ディスクリプタは、以下のように指定します。

var descriptor = {
    name: 'SampleDataModel',
    base: '@SampleBaseDataModel',
    schema: {...}
};
var model = sample.dataManager.createModel(descriptor);
プロパティ名説明
nameデータモデルの名前。必須項目です。
base継承元となるデータモデル。継承元がない場合は指定しなくてかまいません。(詳細はリファレンス(仕様詳細) » データモデルの継承をご覧ください。)
schemaデータモデルの持つプロパティの定義。詳細は後述。

スキーマ

スキーマは、ディスクリプタの中に記述します。各データアイテムに持たせたいプロパティの名をキーにし、その名前のプロパティが持つ性質をオブジェクトの型値で記述します。

1つのディスクリプタ(スキーマ)はid:trueなキーを必ず1つだけ持つ必要があります。

schema: {
    propertyKey1: {
        id: (true/false),
        type: (type),
        enumValue: [(enum-values)],
        defaultValue: (value),
        depend: {
           ...
        },
        constraint: {
           ...
        }
    },
    propertyKey2: {...},
    propertyKey3: {...},
    ...,
}

なお、型・制約を全く指定せず、「この名前のプロパティが存在する」ことだけを記述したい場合は
nullを代入してください(以下の例を参照)。

schema: {
    propertyKeyA: null
}

性質には以下の項目を指定できます。指定の必要がない場合はすべて省略可能です。

id

プロパティがこのデータモデルのID属性となるかどうかをtrueまたはfalseで指定します。省略した場合はfalseです。

データモデルを作成するには、id:trueが指定されているプロパティが必ず1つ必要です。複数指定されている、または1つも指定されていない場合はデータモデルを作成することができません。

id指定をしたプロパティのtype(後述)には'string'または'integer'のみを指定できます。デフォルトは'string'になります。

type

プロパティに格納できる型を文字列で指定します。type指定すると、指定した型以外のもので値が更新されたときにエラーになります。省略した場合はanyです。
プロパティにオブジェクトを代入したい場合はany型を指定してください。

指定できる型は、以下の通りです。

type格納可能な値
stringnull、文字列、Stringラッパークラス
numbernull、数値、Numberラッパークラス、"12.3"のような数値に変換可能な文字列
integernull、整数値、値が整数値であるNumberラッパークラス、"12"のような整数値に変換可能な文字列
booleannull、真偽値、Booleanラッパークラス
@DataModelnull、"@"に続けて書いた名前のデータモデルが持つデータアイテム
enumnull、enumValueに指定された配列に含まれるいずれかの要素
any任意の値(undefined、null、オブジェクト、配列を含む)

どのタイプについても、nullを格納できます。undefinedはany以外に格納することはできません。
データアイテム生成時にnullを格納させたくない場合は、後述のdefaultValueconstraintの仕組みを使用してください。

値は、タイプに合わせて暗黙的に型変換が行われます。ただし、

型変換対象となる型
ラッパークラス → プリミティブ (アンボクシング)string, number, integer, boolean
文字列 → 数値number, integer

の変換のみです。数値 → 文字列の変換は行われません。

文字列→数値の自動型変換は、ビュー(DOM要素)から値を取得してモデルに格納する際の記述の簡便さのために用意しています。
数値→文字列や、また数値→真偽値、真偽値→文字列など任意の型変換を行うと意図しない挙動を生みやすく、間違った値がセットされてしまう可能性が高くなるため、行わないようにしています。

配列指定

"string[]", "any[]"のように、あるプロパティを、特定の型を要素とする配列であると宣言できます。
配列指定した場合は、各要素が指定された型を満たす要素を持つ配列のみを格納できるようになります。

例えば、"string[]"のように指定した場合は、

  • ['abc', 'DEF']

"any[]"のように指定した場合は、

  • [1, "ABC", [1, 2]]

のような値を格納することができます。

enumValue

enumValueに格納できる値を配列で指定します。type:enum を指定している場合は、省略できません。

var model = manager.createModel({
    name: 'EnumTestModel',
    schema: {
        id: {
            id: true
        },
        val: {
            type: 'enum',
            enumValue: [1, 'a', window]   // enumValueを設定
       }
    }
});

var item = model.create({id:'1'});

item.get('val');           // null 初期値はnull

item.set('val', 'a');      // enumValueに列挙した値に一致するのでセットできる
item.set('val', 'b');      // セットできない
item.set('val', null);     // nullはセットできる

defaultValue

プロパティのデフォルト値を指定します。

var model = manager.createModel({
    name: 'DefaultValueTestModel',
    schema: {
        id: {
            id: true
        },
        val: {
            type: 'string',
            defaultValue: 'abc'    // defaultValueを設定
       }
    }
});

var item = model.create({id:'1'});

item.get('val');           // 'abc' defaultValueで設定した値が初期値として格納されている

depend

同一データモデル内のプロパティの値に依存する値を持たせたいときに指定します。
※depend指定されたプロパティには値をセットすることはできません(defaultValueも設定できません)。
値は通常のプロパティと同様、DataItemのget()メソッドで取得することができます。

depend.onに依存するプロパティ名(複数ある場合は配列)、depend.calcに値を計算する関数を指定します。
onで指定したプロパティのうちいずれか1つ以上が変更されると、自動的にcalcに設定した関数が呼ばれ、値が更新されます。
計算された値は、再びonで指定したプロパティが変更されるまで内部に保持されます。

データアイテムの初期生成時には、全依存プロパティのcalcメソッドが呼ばれます。

例えば、合計金額や、フォーマットした値などを格納しておくのに便利です。

記述例:

schema: {
    id: {id:true},

   // 単価
   unitPrice: {
        type: 'integer'
    },

   // 数量
   amount: {
        type: 'integer'
    },

   // 商品
   name: {
        type: 'string'
    },

   // 単価×数量
   totalPrice: {
        type: 'integer',
        depend: {
            on: ['unitPrice', 'amount'], // 同一データモデル内の、依存するプロパティを記述
           calc: function(ev){
               // onに指定されたプロパティが更新されたときにこの関数が実行されます。
               // 引数はチェンジイベントオブジェクト
               // thisはデータアイテムインスタンス

               return this.get('unitPrice') * this.get('amount');
            }
        }
    },

   // "商品:単価×数量"
   label: {
        type: 'string',
        depend: {
           on: ['name', 'totalPrice'],  // depend指定されている項目をさらに依存先に指定できる
          calc: function(ev) {
              return this.get('name') + 'は' + this.get('totalPrice') + '円分あります';
           }
        }
    }
}

depend指定されたプロパティを、さらに別のプロパティのdepend.onに指定すると、依存関係を連鎖させることができます。

上のソースコードの例では、

  1. unitPriceの値を変更
  2. unitPriceに依存するtotalPriceの値を計算
  3. totalPriceに依存するlabelの値を計算

の順番で実行されます。

依存関係が連鎖しているときは、必ずその連鎖の順番通りに値を計算します。

constraint

格納できる値に制約を掛けられます。掛けられる制約は以下の通りです。

プロパティ名説明
notNullbooleantrueを指定した場合、プロパティにnull、undefined値を格納できないようにします。
notEmptybooleantrueを指定した場合、プロパティにnullと空文字を格納できないようにします。
この制約は、type指定が'string' のプロパティに適用されます。
minnumberまたはinteger最小値を指定し、指定した値より小さい値を格納できないようにします。
(つまり、この値「以上」の値しか代入できなくなります。)
この制約は、type指定が'number'または'integer'のプロパティに適用されます。
maxnumberまたはinteger最大値を指定し、指定した値より大きい値を格納できないようにします。
(つまり、この値「以下」の値しか代入できなくなります。)
この制約は、type指定が'number'または'integer'のプロパティに適用されます。
minLengthinteger文字列の最短値を指定し、指定した値より短い文字列を格納できないようにします。
この制約はtype指定が'string'のプロパティに適用されます。
maxLengthinteger文字列の最長値を指定し、指定した値より長い文字列を格納できないようにします。
この制約はtype指定が'string'のプロパティに適用されます。
patternRegExp正規表現を指定し、指定した正規表現にマッチしない文字列を格納できないようにします。
この制約はtype指定が'string'のプロパティに適用されます。

例:

point: {
    type: 'integer',
    constraint: {
        notNull: true,   // 必ず値を格納する必要がある。
       min: 0,          // 0以上、
       max: 100         // 100以下の値のみを格納できる。
   },
    defaultValue: 0
}

各タイプの初期値

defaultValue指定を省略した場合の初期値は、type指定が配列指定でないならnull配列指定ならオブザーバブルな空配列です。

オブザーバブルな配列(ObservableArray)とは、各種API呼び出しを外部から検知できるように、
API呼び出し時にイベントを発火するようにした配列(と同じAPIを持つオブジェクト)です。
詳しくはリファレンス:ObservableArrayをご覧ください。

ObservableArrayは通常の配列と同じAPIを持ちますが、厳密には配列とまったく同じではありません。
特に、obsArray[2] = 'a'; のようにインデックス指定で値を代入すると
その代入を検知することはできないので注意してください。
(代入は、代わりにpush(), shift(), splice()などのメソッドを使用してください。)

type指定が配列指定でかつdefaultValueに配列を指定した場合、予めObservableArrayにそのdefaultValueの各要素をシャローコピーして初期値に持ちます。

var numArray = [1, 2];
var model = manager.createModel({
    name: 'SampleModel',
    schema: {
        id: {
            id: true
        },

       // defaultValue指定のないtype:'number'のプロパティ
       num: {
            type: 'number'
        },

       // defaultValue指定のないtype:'number[]'のプロパティ
       numArray: {
            type; 'number[]'
        },


       // defaultValue指定されたtype:'number[]'のプロパティ
       numArray2: {
            type: 'number[]',
            defaultValue: numArray   // [1, 2]
       }
    }
});

// id以外の値を設定せずにデータアイテムを生成
var item = model.create({
    id: '001'
});

item.num           // null
item.numArray      // 空のObservableArray
item.numArray2     // [1, 2] を要素に持つObservableArray

// 配列指定された項目はObservableArrayなので、
// defaultValueに指定した配列とデータアイテムが持つObservableArrayはインスタンスが異なる
alert(item.numArray2 === numArray)  // false

Copyright (C) 2012-2017 NS Solutions Corporation, All Rights Reserved.