nexacro platformでは、アプリケーションの開発時に使用するスクリプトは、HTML5仕様で使用されるスクリプトに基づいて開発されました。このため、既存のWeb開発者が個別にスクリプト言語を身につけなくても、nexacro platformスクリプトを作成することができます。
ただし、HTML5仕様はまだ開発されており、まだ提供されていませんが、企業内で必要な機能をサポートするために、nexacro platform自体でサポートしているスクリプトも提供されます。そのため、最適の性能を出すアプリケーションを作成するためには、基本的なスクリプト言語と共にnexacro platformスクリプト言語の基本的な知識が必要です。
この章では、既存のバージョンから変更されたスクリプト言語を説明します。
有効範囲(Scope)
有効範囲は、アクセス可能な変数の範囲と関連した内容を説明します。有効範囲または領域と表記し、英語表記そのまま使用する場合もあります。業務に使用するアプリケーションは、複数の画面を同時に操作し、一つの変数を複数の画面で参照する場合が多いが、このような場合、どのように必要なリソースにアクセスできるかどうか有効範囲を通じて調べられます。
this
ADLやフォームで使用されるアイテムの有効範囲を指定するときは、常にthisを使用します。変数だけでなく、プロパティ、フォーム間の参照時にも適切な有効範囲を指定する必要があります。
フォーム内の変数は、次のように宣言します。
this.formvalue = 4;
関数を宣言する場合にも有効範囲を指定する必要があります。また、関数内でフォーム内に宣言された変数を参照するときも、有効範囲を指定する必要があります。
this.formvalue = 4; this.test = function() { this.formvalue = 3; this.parent.value = 3; this.parent.parent.value = 3; }
traceやalertのようなメソッドは、指定された有効範囲によって他のメソッドが実行されます。alert()のみ使用することとthis.alret()を使用することは、お互いに別々のメソッドを実行することです。
this.Button00_onclick = function(obj:Button, e:nexacro.ClickEventInfo) { alert(e.button); this.alert(e.button); }
但し、関数内で宣言された変数は、有効範囲を個別に指定せずに使用可能であり、パラメータとして渡された値も有効範囲を指定せずに使用することができます。
this.Button00_onclick = function(obj:Button, e:nexacro.ClickEventInfo) { obj.set_text("button"); var a = 3; trace(a); // 3 }
関数の宣言時にも有効範囲を指定して該当するアプリケーションやフォームのメンバーに含まれるようにします。
this.Button00_onclick = function(obj:Button, e:nexacro.ClickEventInfo) { ... }
eval関数でフォームにアクセスする場合にもthisを使用する必要があります。
eval("this.formfunc()");
以前のバージョンで使用していたことと同じように関数を宣言することもできますが、Globalで処理され、以降のサポートが中止されることがあるのでお勧めしません。
function Button00_onclick(obj:Button, e:nexacro.ClickEventInfo)
{
...
}
Global
nexacro platformスクリプト内で有効範囲を指定していない変数や関数はすべて、最上位Globalメンバーとして扱われます。
以下のように有効範囲を指定せずに使用されたスクリプトは、すべてGlobalに処理されます。関数の外で varキーワードを使用する場合でも、Globalとして処理されます。
globalvar = 2; var globalvar2 = 3;
関数内で使用された変数でも有効範囲を指定しない場合は、すべてGlobalとして処理されます。ただし、varキーワードを使用して定義した変数は、関数の外で使用することができません。
this.test = function() { trace(globalvar); //2 trace(globalvar2); //3 value = 4; var localvar = 5; } this.test = function() { trace(value); // 4 trace(localvar); // ReferenceError: localvar is not defined }
Form内で他のスクリプトファイルを includeする場合には、内部的にスクリプトを関数として処理します。そのため、varキーワードを使用する場合にはご注意ください。
たとえば、includecode.xjsファイル内に定義された変数が実際にgenerateされた includecode.xjs.jsコードは、以下の通りです。(generateされたコードは、バージョンによって異なる場合があります。)
$r_title(includecode.xjs) bbb = "bbb"; var ccc = "ccc";
$r_title(includecode.xjs.js) (function() { return function(path) { var obj; // User Script this.registerScript(path, function() { bbb = "bbb"; var ccc = "ccc"; }); this.loadIncludeScript(path); obj = null; }; } )();
関数を宣言するか、呼び出すときにも有効範囲を指定する必要があります。次のスクリプトで test()とthis.test()は、別の関数を呼び出します。有効範囲を指定せずにtest()を呼び出すことになると、Globalに宣言されたtest関数を呼び出します。
this.Button00_onclick = function(obj:Button, e:nexacro.ClickEventInfo) { test(); this.test(); }
以下のように有効範囲なしに指定された関数は、Globalとして処理されます。
Button00_onclick = function(obj:Button, e:nexacro.ClickEventInfo) { ... } function Button00_onclick(obj:Button, e:nexacro.ClickEventInfo) { ... }
Alert()、Confirm()、Trace()メソッドをGlobalに使用することができます。以前のバージョンのようにフォームメソッドで使用するには、thisを使って有効範囲を指定する必要があります。
dialog(), open(), exit(), transaction()のようなアプリケーションやフォームメソッドは、該当する有効範囲を指定する必要があります。
//application
application.open("");
application.exit("");
application.transaction("");
//Form
this.close("");
this.go("");
//ADL
this.open("");
this.exit("");
this.transaction("");
アプリケーション全体で使用したい変数は、Global変数ではなく、アプリケーション変数として登録して使用することをお勧めします。
Expr
exprスクリプトはnexacro platformの内部的にバインドされたDatasetに基づいて処理されるため、別の有効範囲を指定しなくても使用することができます。但し、バインドされていないDatasetに直接アクセスするには、有効範囲を指定する必要があります。
以下のようにバインドされたDatasetにexprを使用する場合には、thisをつけません。
<Cell text="expr:Column00"/> <Cell text="expr:Column00.min"/> <Cell text="expr:currow"/> <Cell text="expr:rowposition"/> <Cell text="expr:getSumNF('col0')"/>
Dataset.set_filterstr("Column00=='test'"); Dataset.filter("Column00=='test'");
バインドされたGrid、Dataset、Cellを指定する場合には、下記のようなディレクティブを使用します。
Grid: comp dataset: dataset Cell: this
<Cell text="expr:this.col"/> <!-- cell --> <Cell text="expr:dataset.rowcount"/> <!-- binded dataset --> <Cell text="expr:comp.currentcell"/> <!-- grid --> <Cell text="expr:dataset.parent.func1()"/> <!-- form --> <Cell text="expr:comp.parent.func1()"/> <!-- form -->
フォームに関するディレクティブが別々に提供されず、必要によりcomp.parentまたはdataset.parentのようにアクセスします。
フォーム内の関数にアクセスするとき、comp.parent.func()の形式を使用せずにthisを使用すると、エラーとして処理されます。exprスクリプトで、thisはcellを指します。
<Cell text="expr:this.func01()"/>
コンポーネントのプロパティにExprとTextが一緒にある場合、画面に表示されるテキストを返すdisplaytextプロパティを使用することができます
this.Button00.set_text("text"); this.Button00.set_expr("1+1"); trace(this.Button00.text); // "text" trace(this.Button00.expr); // "1+1" trace(this.Button00.displaytext); // "2"
lookup
lookupメソッドは、有効範囲を指定してアクセスが困難な場合に使用できるように設計された追加メソッドです。idまたは関数名を使用して必要なオブジェクトや関数を検索することができます。
lookupメソッドは、次の形式で使用できます。
Form.lookup( strid ); Frame.lookup( strid ); Application.lookup( strid ); EventSyncObject.addEventHandlerLookup( eventid, funcid, target );
実際のコードでは、次のように使用されます。
// thisから上位に検索してobjectidに該当するオブジェクトを返す var obj = this.lookup("objectid"); // thisから上位に検索してfn_onclickに該当するオブジェクトを返す this.lookup("fn_onclick")(); // thisから上位に検索してfn_onclickに該当する関数をイベントハンドラで処理 btn00.addEventHandlerLookup( "onclick", "fn_onclick", this );
イベントハンドラ
イベント処理のためのイベントハンドラは、nexacro studioプロパティウィンドウで追加したり、各コンポーネント、オブジェクトに提供するメソッドを使用してスクリプトから追加することができます。
メソッド
スクリプト内でイベントの処理のためにイベントハンドラを追加、設定、削除することができるメソッドを提供します。既存のバージョンでは、addHandler、setHandler、removeHandlerの3つのメソッドを提供しましたが、該当メソッドはこれ以上サポートしておりません。
addEventHandler( eventid, funcobj, target )
addEventHandlerLookup( eventid, funcstr, target )
setEventHandler( eventid, funcobj, target )
setEventHandlerLookup( eventid, functstr, target )
removeEventHandler( eventid, funcobj, target )
removeEventHandlerLookup( eventid, funcstr, target )
イベントを処理する関数の有効範囲によって、適切なメソッドを選択して使用します。
this.btn00.setEventHandler("onclick", this.fn_onclick, this); this.dataset00.addEventHandlerLookup("onrowposchange", "fn_onchange", this);
addEventHandlerLookup, setEventHandlerLookup, removeEventHandlerLookupメソッドは、アプリケーションの性能に影響を与える可能性があるので、必要な場合のみ使用をお勧めします。
btn00.onclick.addHandler(button00_onclick) 形式はもうサポートしません。
イベントをプロパティウィンドウで作成すると、下記のように文字列に設定されます。
<Button id="Button00" ... onclick="Button00_onclick"/>
該当コードは、ビルド処理後、変換されたJavaScriptコードでは、下記のようにthisのディレクティブを付けて生成されます。
this.Button00.addEventHandler("onclick", this.Button00_onclick, this);
タイプ
nexacro studioでイベントハンドラ関数にパラメータを設定するときに、オブジェクトのタイプを指定できます。タイプは、JavaScriptの標準的な構文ではなくnexacro studioの内部で開発のしやすさを提供するためにサポートされる形式です。
this.Button00_onclick = function(obj:Button, e:nexacro.ClickEventInfo) { trace(obj.text); }
入力されたタイプの値を基準にnexacro studioでコードヒント機能をサポートします。
該当コードをJavaScriptコードに変換するときは、タイプの値を削除します。
this.Button00_onclick = function(obj, e) { trace(obj.text); }
オブジェクトタイプを指定しなくても、アプリケーションの実行には影響を与えません。
イベントハンドラ関数以外の関数では、オブジェクトタイプをサポートせず、アプリケーションの動作に影響を与えることがあります。
Setter
ECMAScript5からSetter/Getterを使用して変数のアクセス制限を処理することができます。但し、IE8以下のウェブブラウザでサポートできない仕様であるため、nexacro platformでは、別のSetMethodを提供します。
SetMethod
たとえば、Buttonコンポーネントのtextプロパティを使用するときは、以下のように使用することができます。
this.Button00.set_text("text"); trace(this.Button00.text);
以下のようにプロパティの値を直接アクセスする方法はこれ以上サポートされません。
Button00.text = "text";
ユーザーが手動で追加したオブジェクトのプロパティにアクセスする場合は、既存のようにアクセスすることができます。
<Button myprop="333">
Button00.myprop = "333";
Button00.mytext = "text";
スタイルのプロパティにアクセスする方法もSetMethodを使用する必要があります。追加されたSetMethodには、サブプロパティまで含まれています。既存のプロパティは、値を取得する場合にのみ使用することができます。
this.Button00.style.set_color('aqua'); trace(this.Button00.style.color); // 'aqua'
setメソッドを呼び出す前に、スタイルプロパティ値を取得しようとすると、null値が出ることがあります。
但し、CSSコードは、既存と同じです。
Button { background : red; }
ActiveX(プラグイン)やアプレットコンポーネントを使用するとき、プロパティを指定したり、メソッドを呼び出す方法も下記のように使用します。
this.ActiveX00.setProperty("prop1", 3 );
var v = this.ActiveX00.getProperty("prop1");
this.ActiveX00.callMethod("method1", arg1, arg2 );
var v = this.ActiveX00.callMethod("method2");
動的なプロパティ
プロパティ値を取得することは、既存と同じですが、例外的に動的にプロパティ値が変更されたオブジェクトは、別のGetMethodを提供します。Systemオブジェクトのcurx、cury、screenwidth、screenheightの4つのプロパティは追加されたメソッドを使用する必要があります。
System.getCursorX(); System.getCursorY(); System.getScreenWidth(); System.getScreenHeight();
コンポーネントタイプによって使用していないプロパティにアクセスすることができません。例えば、Calendarコンポーネントのタイプがspinではない場合は、次のプロパティにアクセスすることができません。
this.Calendar.spindownbutton this.Calendar.spinupbutton
Calendarコンポーネントでspindownbuttonプロパティは、コントロールプロパティ(Control Property)と呼ばれ、プロパティ自体を文字列として出力すると、[object ButtonControl]と表示されます。
その他の変更と制約事項
nexacroメソッド
ECMAScriptでサポートされていないメソッドをnexacro platform自体に追加して使用していたことを、基準に従って変更しながら、これ以上サポートしておりません。その代わりに該当メソッドは、nexacroメソッドとして別途提供します。
例えば、Mathオブジェクトで提供していたメソッドのうちに二つの引数をサポートするfloor、ceil、roundメソッドは、これ以上提供されません。該当メソッドを使用するには、nexacroメソッドで使用する必要があります。
//Math.floor( v, digit ); nexacro.floor( v, digit ); //Math.ceil( v, digit ); nexacro.ceil( v, digit ); //Math.round( v, digit ); nexacro.round( v, digit );
また、JavaScriptで予約語として使用されるいくつかのオブジェクト名称が変更されました。
//new Image(); new nexacro.Image();
予約語と重複していない残りコンポーネントもTypeDefinition内のclassnameがnexacro.Buttonのような形式に変更されました。ただし、既存のようにButtonをそのまま使用することもできます。
this.button00 = new Button(); or this.button00 = new nexacro.Button();
プロパティやオブジェクトも予約語と衝突して一部変更されました。
Component.class → Component.cssclass
Export.export() → Export.exportData()
Buffer.delete() → Buffer.remove()
VirtualFile.delete() → VirtualFile.remove()
動作変更
JavaScriptでサポートしていないか、別の方法で動作するいくつかの項目が修正されました。
- <> 比較演算子をサポートしません。
<> 比較演算子をこれ以上はサポートしません。他の値を比較するときは != 演算子を使用してください。
- switch文内の文字列処理方法の変更
以前のバージョンでは、switch文内で、case "2"とcase 2が同じ方法で処理れていたことを、別々の値として処理します。
- 正規表現 /gオプションの適用方法の変更
正規表現で /gオプションを使用せずreplaceを適用すると、一つの項目のみ変更されます。すべての項目を変更するためには、/gオプションを適用する必要があります。
オブジェクト名の生成時の制約
コンテナのメンバであるプロパティ、メソッド名と同じChildNameを作成することができません。たとえば、フォームは、textというプロパティを持っていますが追加されたボタンコンポーネントのidをtextに指定することができません。以下のような場合は、ボタンが作成されません。
<Form text="formtext"> <Layouts> <Layout> <Button id="text'>
DatasetのようなInvisibleオブジェクトも、Arrayのメンバーで処理されてlengthのようなプロパティをidで指定することができません。以下のような場合、カラム(列)が生成されません。
<Objects> <Dataset id="Dataset00"> <ColumnInfo> <Column id="length" type="STRING" size="256"/> </ColumnInfo>
変数、関数名の作成時の制約事項
変数名や関数名の前にアンダーバー(_)が含まれている場合、nexacro platformライブラリで使用する変数や関数と競合することがあります。これにより、画面が表示されないか、またはアプリケーションが意図と異なる方向に動作することがあります。
例えば、次の場合、ロードが完了せず、画面が表示されません。nexacro platformライブラリで使用される_is_loading変数と同じ名前で変数名を作成しました。
this._is_loading = true; this.Button00_onclick = function(obj:Button, e:nexacro.ClickEventInfo) { trace(this._is_loading); }
アンダーバー(_)を含んでいなくても、nexacro platformライブラリで使用されるいくつかの変数名や関数名と競合することがあります。
例えば、次の場合、コンポーネントの作成が完了せず、画面が表示されません。nexacro platformライブラリで使用されるcreateComponent関数と同じ名前で関数名を作成しました。
this.createComponent = function() { trace('createComponent '); }