Model, View 템플릿, Action 개발하기

Model 만들기

Model은 화면에서 다루어야 하는 데이터를 설정합니다. Model 필드값에 따라 컴포넌트를 배치할 수 있고 Dataset 오브젝트의 컬럼으로 등록해 Grid 컴포넌트와 바인딩해서 데이터를 표현할 수 있습니다. Model은 단독으로 사용되지 않고 View 템플릿과 연결해서 사용합니다. View 컴포넌트에 Model을 연결할 때 View 템플릿을 선택하고 View 템플릿에서 작성한 로직에 따라 콘텐츠를 생성합니다.

Model 서비스 등록하기

1

Project Exeplorer에서 [TypeDefinition> Services] 항목을 선택합니다.

2

User Service 항목에 서비스를 추가합니다. Type 항목은 "model"로 선택하고 PrefixID를 설정합니다.

Easy UI 패널 표시하기

새로운 Model을 만들기 위해서는 Easy UI 패널을 활성화해주어야 합니다.

1

메뉴 [Easy UI > View > Easy UI] 항목을 선택합니다.

2

Easy UI 패널이 표시되면 Model 탭을 선택합니다.

3

Model 서비스 항목을 오른쪽 마우스로 클릭해 컨텍스트 메뉴를 실행하고 [Add] 항목을 선택해 Model Wizard를 실행합니다.

Model Wizard에서 Model 만들기

Easy UI 패널에서 Model 탭을 선택하고 Model Wizard를 실행합니다. Easy UI 패널을 띄우지 않고 메뉴 [File > New > Model] 항목을 선택해도 Model Wizard를 실행할 수 있습니다.

1

Model Name을 입력합니다.

Location 항목은 앞에서 생성한 모델 서비스 항목으로 설정됩니다. Model Name 값을 입력하면 Service ID는 Model Name과 같은 값이 입력됩니다. 외부 서비스에 접근해서 데이터를 받아오는 경우에는 Service URL을 설정할 수 있습니다.

모델 서비스를 미리 등록하지 않은 경우에는 Location 항목 옆에 있는 버튼을 클릭해서 [Add New Service] 창을 실행하고 모델 서비스를 추가할 수 있습니다.

2

[Next] 버튼을 클릭하고 추가할 속성(Field Attribute) 정보를 추가합니다.

[+] 버튼을 클릭해서 직접 속성을 추가하고 설정할 수도 있으며 [Add User Attribute] 기능을 사용할 수도 있습니다. 예제에서는 [Add User Attribute] 기능을 사용합니다.

3

설정 버튼을 클릭해 [Add User Attribute] 창을 실행하고 새로운 속성을 추가합니다.

예제에서는 uselabel이라는 속성을 선택하고 추가합니다. [Target List] 항목 중 "Predefined"를 선택하고 [Attribute List] 항목에서 "uselabel"을 체크해서 [User Attribute List]에 옮깁니다.

4

[Next] 버튼을 클릭하고 [+] 버튼을 클릭해 Field List 항목을 추가합니다.

항목을 추가한 후에 Field Type 값은 수정할 수 있습니다. Field Type 값은 그 자체로 기능을 가지는 것은 아니고, View 템플릿에서 화면 구성 시 해당하는 필드값에 어떤 컴포넌트나 기능을 적용할지 참조하는 값입니다.

5

[Finish] 버튼을 클릭하고 Model을 만듭니다. 만들어진 Model은 Easy UI 패널 Model 탭에서 확인할 수 있습니다.

View Template에서 User Attribute 목록 가져오기

1

필드 정보 확인 시 [+] 버튼을 클릭하고 [Add From View Template] 항목을 선택합니다.

2

User Attribute 목록을 가져올 View Template을 선택합니다.

fn_GetFieldUserAttributeList 함수가 작성된 View Template 목록만 표시됩니다.

3

Attribute List에서 추가할 User Attribute 항목만 체크합니다.

User Attribute 항목 옆에 있는 버튼을 클릭하면 상세 정보를 확인할 수 있습니다.

4

선택한 User Attribute 항목이 추가된 것을 확인합니다.

Model 정보 수정하기

모델 항목을 더블클릭하거나 컨텍스트 메뉴에서 [Edit] 선택 시 편집 화면으로 이동합니다.

편집 화면에서 [Edit Attribute] 버튼을 클릭하면 [Edit Field Attribute] 창으로 이동합니다.

id, serviceid, serviceurl 항목값은 속성창에서 수정할 수 있습니다.

View 템플릿 만들기

View Template Wizard에서 View 템플릿 만들기

프로젝트 생성 시 아래와 같이 샘플 View 템플릿 2개가 View 템플릿 폴더로 복사됩니다. View 템플릿 항목을 더블클릭하면 스크립트를 확인할 수 있습니다. 예제에서는 샘플 View 템플릿을 사용하지 않고 새로운 View 템플릿을 만듭니다.

1

Easy UI 메뉴에서 [Add] 항목을 선택해 View Template Wizard를 실행합니다. Easy UI 패널을 띄우지 않고 메뉴 [File > New > View Template] 항목을 선택해도 View Template Wizard를 실행할 수 있습니다.

2

Name을 입력합니다.

3

View Type을 선택하거나 입력합니다.

기본 제공되는 Type은 "FreeForm", "GridView" 2가지이며, 다른 값을 직접 입력해서 추가할 수 있습니다. 직접 추가한 View Type 값은 View Template Wizard 실행 시 목록으로 표시됩니다. 샘플과 구분할 수 있도록 View Type 항목값을 "ViewSample"로 입력합니다.

4

[Finish] 버튼을 클릭하고 View 템플릿을 만듭니다. 만들어진 View 템플릿은 Easy UI 패널 View Template 탭에서 확인할 수 있습니다.

View 템플릿 스크립트 편집하기

View Template Wizard에서 View 템플릿을 만들거나 Easy UI 패널에서 View 템플릿 항목을 더블 클릭하면 [파일명].xviewgen이라는 파일이 편집창에서 열립니다. 해당 스크립트를 편집해서 원하는 기능을 구현할 수 있습니다.

기본적인 인터페이스 함수가 작성되어 있으며 필요한 정보를 주석으로 제공합니다.

View 템플릿에서는 2개의 함수를 만들어야 합니다. fn_GetViewAttributeList 함수는 Model 정보와 상관없이 추가로 지원하는 기능 처리 여부를 확인하기 위한 용도로 사용합니다. 예제에서는 버튼 생성 여부를 물어보고 사용자의 선택에 따라 버튼 UI를 생성합니다. fn_GetViewGenerationResult 함수는 넥사크로 스튜디오에서 사용자가 선택한 Model을 포함한 3가지 정보에 대한 화면 UI를 구성할 정보를 반환합니다.

다음 내용에서는 fn_GetViewAttributeList 함수와 fn_GetViewGenerationResult 함수에서 받는 매개변수는 어떤 형태이고 반환해야 하는 값은 어떤 형태인지 살펴보겠습니다.

fn_GetViewGenerationResult

매개변수(fieldarray, contents, generationattr) 값을 기반으로 생성된 View contents 오브젝트를 반환하는 함수입니다. fn_GetViewGenerationResult 함수에서 사용하는 매개변수와 반환하는 값은 JSON 형식의 오브젝트를 사용합니다.

Syntax

fn_GetViewGenerationResult(fieldarray, contents, generationattr)

Parameters

매개변수

타입

설명

fieldarray

Object

Model Field 정보

contents

Object

View 정보

generationattr

Object

View Generation 속성 정보

Return

타입

설명

String

referenceinfo를 제외한 contents 형식의 오브젝트를 문자열로 반환합니다.

반환값 JSON 형식에 대한 상세 설명은 fn_GetViewGenerationResult 반환값 JSON 형식 내용을 참고해주세요.

fieldarray 매개변수 JSON 형식

선택한 Model 정보입니다. 기본적인 값은 모델 생성 시 필드값이며 "uselabel"과 같은 Attribute를 추가한 경우 같이 넘겨집니다.

{
	"modelinfo": {
		"serviceid": "mdlSample",
		"serviceurl": ""
	},
	"fieldcount": "2",
	"fields": [
		{
			"id": "name",
			"label": "Name",
			"fieldtype": "FreeText",
			"datatype": "STRING",
			"datasize": "80",
			"uselabel" : "true"
		},
		{
			"id": "company",
			"label": "Company",
			"fieldtype": "FreeText",
			"datatype": "STRING",
			"datasize": "80",
			"uselabel" : "true"
		}
	]
}

contents 매개변수 JSON 형식

Model을 연결하려고 하는 View 컴포넌트 정보입니다. View 컴포넌트의 Border 영역을 제외하고 컴포넌트를 배치할 수 있는 실제 너비와 높이(referenceinfo)를 기준으로 컴포넌트를 배치할 수 있습니다. 실제 크기와 각 컴포넌트의 간격, 폰트 크기 등을 고려해 컴포넌트를 배치하게 됩니다.

View 컴포넌트에 이미 연결된 모델 정보가 있거나 다른 컴포넌트가 있다면 Model 정보가 추가되고 Dataset 오브젝트가 포함된 경우 Objects 정보가 추가됩니다. 그 외 View 컴포넌트에 연관된 정보가 같이 넘겨집니다.

{
	"View": {
		"tag": "View",
		"referenceinfo": {
			"realwidth": "490",
			"realheight": "90"
		},
		"attribute": {
			"id": "View00",
			"taborder": "0",
			"text": "View00",
			"viewdataset": "viewdataset",
			"left": "0",
			"top": "0",
			"width": "500",
			"height": "100",
			"border":"5px solid darkkhaki"
		},
		"Model": [],
		"Objects": [
			{}
		],
		"Bind": [
			{}
		],
		"InitValue": [
			{}
		],
		"Script": {}
	}
}

generationattr 매개변수 JSON 형식

ViewAttribute 설정 정보입니다. 각 항목은 fn_GetViewAttributeList 함수에서 반환된 값이며 항목값은 Model 연결 시 View Template Attributes 단계에서 설정한 값입니다.

{
	"attributes": {
		"use_triggerbutton": "true"
	}
}

반환값 JSON 형식

View 템플릿에서 매개변수(fieldarray, contents, generationattr) 값을 기반으로 생성된 View contents 값입니다.

{
	"View": {
		"tag": "View",
		"attribute": {
			"id": "View00",
			"taborder": "0",
			"text": "View00",
			"viewdataset": "viewdataset",
			"left": "85",
			"top": "43",
			"width": "437",
			"height": "110"
		},
		"Model": [
			{
				"fieldid": "name",
				"Components": [
					{
						"tag": "Static",
						"attribute": {
							"id": "Static0",
							"text": "Name",
							"left": 0,
							"top": 0,
							"width": 60,
							"height": 20,
							"font": "normal bold 15pt/normal"
						}
					},
					{
						"tag": "Edit",
						"attribute": {
							"id": "Edit0",
							"left": "Static0:5",
							"top": 0,
							"width": 100,
							"height": 20,
							"font": "normal bold 15pt/normal"
						}
					}
				]
			},
			{
				"fieldid": "company",
				"Components": [
					{
						"tag": "Static",
						"attribute": {
							"id": "Static1",
							"text": "Company",
							"left": 0,
							"top": 30,
							"width": 60,
							"height": 20,
							"font": "normal bold 15pt/normal"
						}
					},
					{
						"tag": "Edit",
						"attribute": {
							"id": "Edit1",
							"left": "Static1:5",
							"top": 30,
							"width": 100,
							"height": 20,
							"font": "normal bold 15pt/normal"
						}
					}
				]
			},
			{
				"fieldid": "",
				"Components": [
					{
						"tag": "Button",
						"attribute": {
							"id": "btn_Trigger",
							"right": 0,
							"top": 0,
							"width": 70,
							"height": 20,
							"text": "Search"
						}
					}
				]
			}
		],
		"Objects": [
			{
				"tag": "Objects",
				"Objects": [
					{
						"tag": "Dataset",
						"attribute": {
							"id": "viewdataset"
						},
						"Dataset": [
							{
								"tag": "ColumnInfo",
								"ColumnInfo": [
									{
										"tag": "Column",
										"attribute": {
											"id": "name",
											"type": "STRING",
											"size": "80"
										}
									},
									{
										"tag": "Column",
										"attribute": {
											"id": "company",
											"type": "STRING",
											"size": "80"
										}
									}
								]
							},
							{
								"tag": "Rows",
								"Rows": [
									{
										"tag": "Row"
									}
								]
							}
						]
					}
				]
			}
		],
		"Bind": [
			{
				"tag": "Bind",
				"Bind": [
					{
						"tag": "BindItem",
						"attribute": {
							"id": "item0",
							"compid": "Edit0",
							"propid": "value",
							"datasetid": "viewdataset",
							"columnid": "name"
						}
					},
					{
						"tag": "BindItem",
						"attribute": {
							"id": "item1",
							"compid": "Edit1",
							"propid": "value",
							"datasetid": "viewdataset",
							"columnid": "company"
						}
					}
				]
			}
		]
	}
}

fn_GetViewAttributeList

View 생성에 필요한 속성 정보를 반환하는 함수입니다.

Syntax

fn_GetViewAttributeList()

Return

타입

설명

String

View Template Attributes 목록 오브젝트를 문자열로 반환합니다.

null 값을 반환하면 View Generation Wizard에서 추가 속성 설정을 처리하지 않습니다.

반환값 JSON 형식

{
	"attributecount": 1,
	"attributes": [
		{
			"id": "use_triggerbutton",
			"edittype": "Boolean",
			"defaultvalue": "true",
			"description": "Create a button for data inquiry (true/false)"
		}
	]
}

edittype 값이 "Enum"인 경우에는 아래와 같이 처리할 수 있습니다.

{
    "attributecount": "1",
    "attributes": [
        {
            "id": "gridtype",
            "edittype": "Enum",
            "defaultvalue": "Single Line",
            "enumlist": [
                "Single Line",
                "Multi Line"
            ],
            "description": "Specifies the generation type of grid."
        }
    ]

edittype 값이 "Layout"인 경우에는 아래와 같이 처리할 수 있습니다.

{
    "attributecount": "1",
    "attributes": [
        {
            "id": "view_layout",
            "edittype": "Layout",
			"userproperties": {
				"propertycount": "1",
				"properties": [
					{
						"id": "gap",
						"edittype": "Number",
						"defaultvalue": 5
					}
				]
			}
        }
    ]

fn_GetFieldUserAttributeList

fn_GetFieldUserAttributeList 함수는 2가지 기능을 지원합니다.

Model 생성 시 User Attributes 처리

Model 생성 시 [Add User Attribute] 설정에서 fn_GetFieldUserAttributeList 함수를 가진 View Template 목록을 Target List에 표시하고 View Template을 선택하면 추가할 수 있는 User Attributes 정보를 표시합니다.

Model 적용 시 User Attributes 처리

View 컴포넌트에 Model 적용 시 선택한 View Template에 fn_GetFieldUserAttributeList 함수가 있다면 User Attributes 정보를 Model 필드에 추가합니다.

Model에서 정의한 User Attribute와 id가 같은 경우에는 Model에서 정의한 User Attribute를 적용합니다.

Syntax

fn_GetFieldUserAttributeList()

Return

타입

설명

String

Model 필드로 추가할 User Attributes 목록 오브젝트를 문자열로 반환합니다.

null 값을 반환하면 Attribute List를 표시하지 않습니다.

반환값 JSON 형식

{
	"attributecount": 1,
	"attributes": [
		{
			"id": "editable",
			"edittype": "Boolean",
			"defaultvalue": "true",
			"description": "Sets whether the field data can be edited."
		}
	]
}

View 템플릿 샘플

예제에서는 2개의 View 템플릿을 생성합니다. viewSampleForm은 Model 정보에 따라 조회 조건 UI를 생성하거나 Grid 컴포넌트에서 선택한 항목의 상세 정보를 표현하는 UI를 생성합니다. viewSampleGrid는 Model 정보에 따라 Grid 컴포넌트를 표현합니다.

아래 샘플에서는 JSON 반환값 형식을 만들기 위해 Object, Array를 사용했는데, 아래와 같이 문자열만으로도 코드를 작성할 수 있습니다.

...
var strDataset1 = "{";
strDataset1 += "\"tag\": \"Dataset\",";
strDataset1 += "\"attribute\": {\"id\": \"viewdataset\"},";
strDataset1 += "\"Dataset\": [";
strDataset1 += "{\"tag\": \"ColumnInfo\",";
strDataset1 += "\"ColumnInfo\": [";
...

샘플 코드에서는 함수 안에 모든 코드를 다 추가했지만, 반환값에 포함되는 각 객체별로 구분해서 별도의 함수를 만들고 결과값을 조합하는 방식이 좀 더 깔끔할 수 있습니다.

viewSampleForm

필드 정보에 따라 Edit 컴포넌트를 생성하고 uselabel 추가 속성이 "true"인 경우에는 Static 컴포넌트를 Edit 컴포넌트 앞에 배치합니다. fn_GetViewAttributeList 함수에서는 use_triggerbutton이라는 항목을 반환하며 Button 생성 여부를 판단합니다.

viewdataset 이라는 id로 Dataset 오브젝트를 생성하고 Edit 컴포넌트 value 속성에 바인딩합니다.

fn_GetViewGenerationResult = function (fieldarray, contents, generationattr) {
    var vResult = "";
	var json_contents = JSON.parse(contents);
	var json_fieldarray = JSON.parse(fieldarray);
	var json_generationattr = JSON.parse(generationattr);
	
	var View = new Object(); // JSON Object	
	var tempInfo;
	var tempPostion;
	
	var ModelArray = new Array();
	var ModelInfo;
	
	var ComponentArray;
	var ObjectsArray = new Array();
	var ObjectArray = new Array();
	var DatasetArray = new Array();
	var ColumnArray = new Array();
	var BindsArray = new Array();
	var BindArray = new Array();

	for (var i in json_fieldarray.fields) {
		ModelInfo = new Object();
		ComponentArray = new Array();
		ModelInfo.fieldid = json_fieldarray.fields[i].id;
		
		tempInfo = new Object();
		tempInfo.tag = "Column";
		tempInfo.attribute = new Object();
		tempInfo.attribute.id = json_fieldarray.fields[i].id;
		tempInfo.attribute.type = json_fieldarray.fields[i].datatype;
		tempInfo.attribute.size = json_fieldarray.fields[i].datasize;
		ColumnArray.push(tempInfo);
		
		if(json_fieldarray.fields[i].uselabel == "true") {
			tempInfo = new Object();
			tempInfo.tag = "Static";
			tempInfo.attribute = new Object();
			tempInfo.attribute.id = "Static"+i;
			tempInfo.attribute.text = json_fieldarray.fields[i].label;
			tempInfo.attribute.left = 0;
			tempInfo.attribute.top = i*30;
			tempInfo.attribute.width = 60;
			tempInfo.attribute.height = 20;
			tempInfo.attribute.font = "normal bold 15pt/normal";
			ComponentArray.push(tempInfo);
		}
		
		tempInfo = new Object();
		tempInfo.tag = "Edit";
		tempInfo.attribute = new Object();
		tempInfo.attribute.id = "Edit"+i;
		tempInfo.attribute.left = "Static"+i+":5";
		tempInfo.attribute.top = i*30;
		tempInfo.attribute.width = 100;
		tempInfo.attribute.height = 20;
		tempInfo.attribute.font = "normal bold 15pt/normal";
		ComponentArray.push(tempInfo);
		
		tempInfo = new Object();
		tempInfo.tag = "BindItem";
		tempInfo.attribute = new Object();
		tempInfo.attribute.id = "item"+i;
		tempInfo.attribute.compid = "Edit"+i;
		tempInfo.attribute.propid = "value";
		tempInfo.attribute.datasetid = "viewdataset";
		tempInfo.attribute.columnid = json_fieldarray.fields[i].id;
		BindArray.push(tempInfo);	
		
		ModelInfo.Components = ComponentArray;
		ModelArray.push(ModelInfo);		
	}
	tempInfo = new Object();
	tempInfo.tag = "ColumnInfo";
	tempInfo.ColumnInfo = ColumnArray;
	DatasetArray.push(tempInfo);
	
	tempInfo = new Object();
	tempInfo.tag = "Rows";
	tempInfo.Rows = new Array();

	var RowInfo = new Object();
	RowInfo.tag = "Row";
	tempInfo.Rows.push(RowInfo);
	DatasetArray.push(tempInfo);

	tempInfo = new Object();
	tempInfo.tag = "Dataset";
	tempInfo.attribute = new Object();
	tempInfo.attribute.id = "viewdataset";
	tempInfo.Dataset = DatasetArray;
	ObjectArray.push(tempInfo);
	
	tempInfo = new Object();	
	tempInfo.tag = "Objects";	
	tempInfo.Objects = ObjectArray;
	ObjectsArray.push(tempInfo);
	
	tempInfo = new Object();
	tempInfo.tag = "Bind";
	tempInfo.Bind = BindArray;
	BindsArray.push(tempInfo);
	
	if(json_generationattr.attributes.use_triggerbutton == "true") {
		ModelInfo = new Object();
		ComponentArray = new Array();
		ModelInfo.fieldid = "";
		
		tempInfo = new Object();
		tempInfo.tag = "Button";
		
		var buttonwidth = 70;
		tempInfo.attribute = new Object();
		tempInfo.attribute.id = "btn_Trigger";
		tempInfo.attribute.right = 0;
		tempInfo.attribute.top = 0;
		tempInfo.attribute.width = buttonwidth;
		tempInfo.attribute.height = 20;
		tempInfo.attribute.text = "Search"
		ComponentArray.push(tempInfo);
		ModelInfo.Components = ComponentArray;
		ModelArray.push(ModelInfo);
	}	

	tempInfo = new Object();
	tempInfo.tag = "View";
	tempInfo.attribute = json_contents.View.attribute;
	tempInfo.Model = ModelArray;
	tempInfo.Objects = ObjectsArray;
	tempInfo.Bind = BindsArray;

	View.View = tempInfo;
	var vResult = JSON.stringify(View);
    return vResult;
};

fn_GetViewAttributeList = function () {
	var attrArray = new Array();
	var attrObj = new Object();
	attrObj.id = "use_triggerbutton";
	attrObj.edittype = "Boolean";
	attrObj.defaultvalue = "true";
	attrObj.description = "Create a button for data inquiry (true/false)";
	attrArray.push(attrObj);
	
	var attr = new Object();
	attr.attributecount = attrArray.length;
	attr.attributes = attrArray;
	
	var strJson = JSON.stringify(attr);
	trace("RE : "+strJson);	
	return strJson;
};

viewSampleGrid

필드 정보에 따라 Grid 컴포넌트와 Dataset 오브젝트를 생성하고 Dataset 오브젝트는 Grid 컴포넌트와 바인딩합니다. fn_GetViewAttributeList 함수는 사용하지 않습니다.

fn_GetViewGenerationResult = function (fieldarray, contents, generationattr) {
    var vResult = "";
	var json_contents = JSON.parse(contents);
	var json_fieldarray = JSON.parse(fieldarray);
	//var json_generationattr = JSON.parse(generationattr);
	
	var View = new Object(); // JSON Object	
	var tempInfo;
	
	var ModelArray = new Array();
	var ModelInfo = new Object();
	ModelInfo.fieldid = "";

	var ComponentArray = new Array();
	var ObjectsArray = new Array();
	var ObjectArray = new Array();
	var DatasetArray = new Array();
	var ColumnArray = new Array();
	
	var GridColumnsArray = new Array();
	var GridRowsArray = new Array();
	var GridBandHeadArray = new Array();
	var GridBandBodyArray = new Array();


	for (var i in json_fieldarray.fields) {
		if(ModelInfo.fieldid != "") {
			ModelInfo.fieldid += ",";
		}
		ModelInfo.fieldid += json_fieldarray.fields[i].id;
		
		tempInfo = new Object();
		tempInfo.tag = "Column";
		tempInfo.attribute = new Object();
		tempInfo.attribute.id = json_fieldarray.fields[i].id;
		tempInfo.attribute.type = json_fieldarray.fields[i].datatype;
		tempInfo.attribute.size = json_fieldarray.fields[i].datasize;
		ColumnArray.push(tempInfo);
		
		tempInfo = new Object();
		tempInfo.tag = "Column";
		tempInfo.attribute = new Object();
		tempInfo.attribute.size = "80";
		GridColumnsArray.push(tempInfo);

		tempInfo = new Object();
		tempInfo.tag = "Cell";
		tempInfo.attribute = new Object();
		tempInfo.attribute.col = i;
		tempInfo.attribute.text = json_fieldarray.fields[i].label;
		GridBandHeadArray.push(tempInfo);		
		
		tempInfo = new Object();
		tempInfo.tag = "Cell";
		tempInfo.attribute = new Object();
		tempInfo.attribute.col = i;
		tempInfo.attribute.text = "bind:"+json_fieldarray.fields[i].id;
		tempInfo.attribute.edittype = "text";
		GridBandBodyArray.push(tempInfo);
	}
	var GridInfo = new Object();
	GridInfo.tag = "Formats";
	GridInfo.Formats = new Array();
	var formatInfo = new Object();
	formatInfo.tag = "Format";
	formatInfo.attribute = new Object();
	formatInfo.attribute.id = "default";
	formatInfo.Format = new Array();
	
	tempInfo = new Object();
	tempInfo.tag = "Columns";
	tempInfo.Columns = GridColumnsArray;
	formatInfo.Format.push(tempInfo);
	
	tempInfo = new Object();
	tempInfo.tag = "Row";
	tempInfo.attribute = new Object();
	tempInfo.attribute.band = "head";
	tempInfo.attribute.size = "24";
	GridRowsArray.push(tempInfo);
	tempInfo = new Object();
	tempInfo.tag = "Row";
	tempInfo.attribute = new Object();
	tempInfo.attribute.size = "24";
	GridRowsArray.push(tempInfo);	

	tempInfo = new Object();
	tempInfo.tag = "Rows";
	tempInfo.Columns = GridRowsArray;
	formatInfo.Format.push(tempInfo);
	
	tempInfo = new Object();
	tempInfo.tag = "Band";
	tempInfo.attribute = new Object();
	tempInfo.attribute.id = "head";
	tempInfo.Columns = GridBandHeadArray;
	formatInfo.Format.push(tempInfo);	
	
	tempInfo = new Object();
	tempInfo.tag = "Band";
	tempInfo.attribute = new Object();
	tempInfo.attribute.id = "body";	
	tempInfo.Columns = GridBandBodyArray;
	formatInfo.Format.push(tempInfo);	
	GridInfo.Formats.push(formatInfo);
	
	tempInfo = new Object();
	tempInfo.tag = "Grid";
	tempInfo.attribute = new Object();
	tempInfo.attribute.id = "Grid"+i;
	tempInfo.attribute.left = 0;
	tempInfo.attribute.top = 0;
	tempInfo.attribute.right = 0;
	tempInfo.attribute.bottom = 0;
	tempInfo.attribute.binddataset = "viewdataset";
	tempInfo.Grid = new Array();
	tempInfo.Grid.push(GridInfo);
	ComponentArray.push(tempInfo);		
		
	tempInfo = new Object();
	tempInfo.tag = "ColumnInfo";
	tempInfo.ColumnInfo = ColumnArray;
	DatasetArray.push(tempInfo);
	
	tempInfo = new Object();
	tempInfo.tag = "Rows";
	tempInfo.Rows = new Array();

	var RowInfo = new Object();
	RowInfo.tag = "Row";
	tempInfo.Rows.push(RowInfo);
	DatasetArray.push(tempInfo);

	tempInfo = new Object();
	tempInfo.tag = "Dataset";
	tempInfo.attribute = new Object();
	tempInfo.attribute.id = "viewdataset";
	tempInfo.Dataset = DatasetArray;
	ObjectArray.push(tempInfo);
	
	tempInfo = new Object();	
	tempInfo.tag = "Objects";	
	tempInfo.Objects = ObjectArray;
	ObjectsArray.push(tempInfo);
	
	ModelInfo.Components = ComponentArray;
	ModelArray.push(ModelInfo);

	tempInfo = new Object();
	tempInfo.tag = "View";
	tempInfo.attribute = json_contents.View.attribute;
	tempInfo.Model = ModelArray;
	tempInfo.Objects = ObjectsArray;

	View.View = tempInfo;
	var vResult = JSON.stringify(View);
    return vResult;
};

fn_GetViewAttributeList = function () {
	return null;
};

Action 만들기

Model과 View 템플릿을 사용해 만든 화면에서 실제 동작할 기능을 설정해주는 단계입니다. Trigger로 지정한 오브젝트에 특정 이벤트가 발생하는 경우 지정한 동작을 처리합니다. 예제에서는 검색창에서 버튼을 클릭하면 Grid 컴포넌트에 데이터를 표시하도록 합니다. 데이터 조회를 위한 Action 속성값에 따라 데이터 조회가 성공했을 때 특정 속성값이면 Alert 대화상자를 표시합니다.

Action은 사용자 모듈 형태로 생성하고 넥사크로 스튜디오에 설치합니다.

넥사크로 모듈 디벨로퍼 beta에서 Invisible Object 프로젝트를 생성해서 Action 모듈을 생성할 수 있습니다.

Action 모듈 프로젝트 생성하기

1

넥사크로 모듈 디벨로퍼를 실행합니다.

넥사크로 스튜디오 설치 시 바로가기를 생성하지 않은 경우에는 설치 폴더에서 "nexacromoduledeveloper17.exe" 파일을 실행합니다.


2

메뉴 [File > New > Project]를 선택해 Project Wizard를 실행합니다.

3

Module 항목에서 Invisible Object를 선택합니다.

4

Project Name을 입력하고 [Next] 버튼을 클릭합니다.

5

Object ID를 입력합니다. Object ID는 Action 오브젝트 이름으로 설정됩니다.

예제에서는 "TestQueryAction"으로 Object ID를 입력합니다. ClassName은 Object ID를 입력하면 자동으로 채워집니다.

6

[Finish] 버튼을 클릭합니다.

프로젝트가 생성됩니다. 상세 옵션 설정은 이번 예제에서는 설정하지 않습니다. 오브젝트의 상세 속성은 프로젝트 생성 이후 언제든지 설정할 수 있습니다.

Action 오브젝트 추가하기

프로젝트 생성 시에는 기본 오브젝트 1개가 생성되며 같은 모듈로 배포할 오브젝트는 추가해주어야 합니다.

1

메뉴 [File > New > Invisible Object]를 선택해 Invisible Object Wizard를 실행합니다.

2

Object ID를 입력합니다.

추가하는 Action 오브젝트의 이름은 "TestAlertAction"입니다.

3

[Finish] 버튼을 클릭합니다.

Action 오브젝트 속성 편집하기

1

Project Explorer에서 TestQueryAction 오브젝트 MetaInfo 항목을 선택하고 속성창에서 아래 속성값을 수정합니다.

subgroup: Action
registration: allow
contents: true

2

contents 속성값을 true로 설정한 후 [ContentsInfo Editor] 설정창을 띄우고 "Contents Format" 속성값을 "json"으로 변경합니다.

17.1.2.300 이후 버전은 Action 오브젝트 생성 시 contents 속성값이 true로 설정됩니다.

이전 버전에서만 참고해주세요.

3

Project Explorer에서 TestAlertAction 오브젝트 MetaInfo 항목을 선택하고 같은 값으로 속성값을 수정합니다.

Action 오브젝트 스크립트 편집하기

1

Project Explorer에서 편집할 Action 오브젝트 스크립트 파일을 더블클릭하거나 컨텍스트 메뉴에서 [Edit] 항목을 선택합니다.

2

Action 오브젝트에 맞게 스크립트 파일을 수정합니다.

Action 스크립트는 nexacro.Action을 상속받아 구현합니다. 기본적인 구조는 아래와 같으며 이벤트 발생 시 run 함수가 실행됩니다. run 함수 내에서 필요한 정보를 수집하고 처리하게 됩니다.

스크립트 내에서 필요한 정보는 Action 오브젝트 속성, 메소드를 사용해 접근할 수 있습니다.

Action 오브젝트 속성, 메소드, 이벤트

(function(nexacro) {
    "use strict";

	if (!nexacro)
		return;
	if (nexacro.TestQueryAction)
		return nexacro.TestQueryAction;

	var TestQueryAction = function(id, parent)
	{
        nexacro.Action.call(this, id, parent);
	};	
		
	var _pTestQueryAction = nexacro._createPrototype(nexacro.Action, TestQueryAction);		
	TestQueryAction.prototype = _pTestQueryAction;
	_pTestQueryAction._type_name = "TestQueryAction";
	_pTestQueryAction.uservalue = null;	
	
	_pTestQueryAction.destroy = function ()
	{
		nexacro.Action.prototype.destroy.call(this);
		this.uservalue = null;
    };

	_pTestQueryAction.set_uservalue = function (v)
	{
		if (v && this.uservalue!== v)
		{		
			this.uservalue= v;
		}
	};

	_pTestQueryAction.run = function ()
	{
	};

    nexacro.TestQueryAction = TestQueryAction;
    return TestQueryAction;
}) (nexacro);

TestQueryAction, TestAlertAction에 사용한 스크립트는 아래와 같습니다.

TestQueryAction 스크립트

trigger 발생 시(버튼 클릭 시) run 함수를 호출합니다. _getArgumentList 함수를 호출해서 매개변수로 넘겨진 Contents 정보와 viewdataset 오브젝트에 저장된 컬럼값을 합친 값을 반환받고 samplefilename에 입력된 값을 가지고 데이터 로딩을 위한 XML 파일을 확인한 후 transaction 메소드를 실행합니다. 예제에서는 XML 파일을 바로 호출하는 것이기 때문에 매개변수가 넘겨지는 값은 trace 메소드를 사용해 출력하고 사용하지는 않습니다.

$r_title(TestQueryAction.js)
(function(nexacro) {
    "use strict";

	if (!nexacro)
		return;
	if (nexacro.TestQueryAction)
		return nexacro.TestQueryAction;

	var TestQueryAction = function(id, parent)
	{
        nexacro.Action.call(this, id, parent);
	};	
		
	var _pTestQueryAction = nexacro._createPrototype(nexacro.Action, TestQueryAction);		
	TestQueryAction.prototype = _pTestQueryAction;
	_pTestQueryAction._type_name = "TestQueryAction";		
	
	_pTestQueryAction.samplefilename = ""; // XML file name	
	_pTestQueryAction.alerttype = false; // TestAlertAction condition
	_pTestQueryAction.targetobj = null;

	_pTestQueryAction.destroy = function ()
	{
		nexacro.Action.prototype.destroy.call(this);
        this.samplefilename = null;
		this.alerttype = null;
        this.targetobj = null;		
    };
    
	_pTestQueryAction.set_samplefilename = function (v)
	{
		if (v && this.samplefilename !== v)
		{		
			this.samplefilename = v;			
		}
	};
	
	_pTestQueryAction.set_alerttype = function (v)
	{
		if (v && this.alerttype !== v)
		{		
			this.alerttype = v;			
		}
	};	
	
    _pTestQueryAction.set_targetobj = function (v)
	{
		if (v && this.targetobj !== v)
		{
			this.targetobj = v;	
		}
    };	


	_pTestQueryAction._getArgumentList = function (strType)
	{
		var argumentlist = this.getContents(strType);
		if (!argumentlist) {
			return;
		}
		if(strType == "model")
		{
			for (var i = 0; i < argumentlist.length; i++)
			{
				var tempDataset = this.parent.lookup(argumentlist[i].viewid).getViewDataset();
				argumentlist[i].value = tempDataset.getColumn(tempDataset.rowposition, argumentlist[i].fieldid);
			}
		}
		return argumentlist;
	};

	_pTestQueryAction.run = function ()
	{
		var targetview = this.getTargetView();
		var viewdataset = targetview.viewdataset;
		var argumentlist = "";

		var modellist = this._getArgumentList ("model");
		var extralist = this._getArgumentList ("extra");
		var outdataset = viewdataset + "=ds_" + viewdataset;

        var callbackfn = "fn_callback";

        if (modellist)
        {
            for (var i = 0; modellist.length > i; i++)
            {
                if (modellist[i].value)
                {
                    argumentlist += modellist[i].name + "=" + modellist[i].value;
                    argumentlist += " ";
                }
            }
        }
		
        if (extralist)
        {
            for (var i = 0; extralist.length > i; i++)
            {
                if (extralist[i].value)
                {
                    argumentlist += extralist[i].name + "=" + extralist[i].value;
                    argumentlist += " ";
                }
            }
        }		
		
		// transaction callback function (onsuccess, onerror event)
		var targetaction = this;
		targetview.form[callbackfn] = function (strSvcID, nErrorCode, strErrorMag)
		{
			if (nErrorCode >= 0)
			{
				targetaction.error = "callback-success";
				targetaction.on_fire_onsuccess();
			}
			else
			{
				targetaction.error = "callback-error";
				targetaction.on_fire_onerror();
			}	
		}

		argumentlist += "dsname=" + viewdataset + " ";
		argumentlist.trim();
		var serviceurl = "Sample::"+this.samplefilename+".xml";
		trace("argumentlist: "+argumentlist);
		trace("outdataset: "+outdataset);
		trace("serviceurl: "+serviceurl);

		targetview.form.transaction("TEST", serviceurl, "", outdataset, argumentlist, callbackfn);
    };		
    
    nexacro.TestQueryAction = TestQueryAction;

    return TestQueryAction;
    
}) (nexacro);

TestAlertAction 스크립트

TestAlertAction 스크립트에서는 run 함수 실행 시 message 속성값을 alert 메소드 파라미터로 담아 실행하는 것이 전부입니다.

$r_title(TestAlertAction.js)
(function(nexacro) {
	"use strict";

	if (!nexacro)
		return;
	if (nexacro.TestAlertAction)
		return nexacro.TestAlertAction;
		
	var TestAlertAction = function(id, parent)
	{
		nexacro.Action.call(this, id, parent);
	};
		
	var _pTestAlertAction = nexacro._createPrototype(nexacro.Action, TestAlertAction);		
	TestAlertAction.prototype = _pTestAlertAction;
    _pTestAlertAction._type_name = "TestAlertAction";		
        
    _pTestAlertAction.message = "";

	_pTestAlertAction.destroy = function ()
	{
		nexacro.Action.prototype.destroy.call(this);
        
        this.message = null;
    };

    _pTestAlertAction.set_message = function (v)
	{
		this.message = v;			
	};

    _pTestAlertAction.run = function ()
	{
        alert(this.message);
	};		
	
	nexacro.TestAlertAction = TestAlertAction;

	return TestAlertAction;

}) (nexacro);

Action 오브젝트 메타인포 속성 편집하기

Action을 모듈로 배포하고 사용하기 위해서 메타인포 파일을 생성해야 합니다.

1

Project Explorer에서 편집할 Action 오브젝트 MetaInfo 항목을 더블클릭하거나 컨텍스트 메뉴에서 [Edit] 항목을 선택합니다.

2

targetview 속성의 세부 정보를 수정합니다.

parent, targetview 속성은 nexacro.Action 기본 속성으로 Action 오브젝트 생성 시 메타인포에 기본값으로 표시됩니다. targetview 항목을 선택하고 속성창에서 정보를 수정합니다.

Group: Action
Edit Type: ViewObjList

3

[Property] 탭에서 [+] 버튼을 클릭해 Action 오브젝트의 속성을 추가합니다.

Action 스크립트 편집 시 Add 메뉴를 사용해 속성을 추가하면 메타인포에도 정보가 추가되지만 스크립트를 직접 편집한 경우에는 메타인포 정보에 추가해주어야 합니다.

TestQueryAction 오브젝트는 아래와 같이 3개의 속성을 추가합니다.

Name: targetobj
Group: Action
Edit Type: ViewChildObjList

Name: samplefilename
Group: Misc.
Edit Type: String

Name: alerttype
Group: Misc.
Edit Type: Boolean
Default Value: false

TestAlertAction 오브젝트는 아래와 같이 1개의 속성을 추가합니다.

Name: message
Group: Misc. 
Edit Type: String

TestAlertAction 오브젝트에서는 targetview 속성을 사용하지 않습니다. 해당 속성 선택 후 Unused 항목을 true로 변경합니다.

메타인포 파일에서 설정한 내용은 Action 연결 시 Controller Wizard에서 아래와 같이 처리됩니다.

group

Controller Wizard에서 보이는 그룹명을 지정할 수 있습니다. 사용자가 쉽게 속성을 인식할 수 있도록 보조적으로 제공하는 정보입니다.

edittype

ObjectInfo 태그에서는 edittype을 "action"으로 설정합니다.

<ObjectInfo ... edittype="action" ...

각 속성 설정 시 edittype을 지정하면 사용자 입력값 형식을 설정할 수 있습니다. 텍스트로 값을 입력하지 않고 목록에서 선택할 수 있도록 기능도 지원합니다. Action에서 사용할 수 있는 edittype은 아래와 같습니다.

edittype

설명

String

문자열을 입력합니다.

Number

숫자를 입력합니다.

Boolean

true, false 값을 선택합니다.

ModelServiceID

Model 목록을 제공합니다.

ViewObjList

현재 Form에서 사용할 수 있는 View 컴포넌트 목록을 제공합니다. refreshinfo 항목을 같이 설정하면 선택한 목록 변경 시 하위 항목에 영향을 미칩니다.

ViewChildObjList

ViewObjList에서 선택한 View 컴포넌트에 포함된 컴포넌트 또는 오브젝트 목록을 제공합니다.

Action 오브젝트 메타인포 RefreshInfo 추가하고 적용하기

2가지 속성이 서로 연결되어 있어서 하나의 속성값을 변경했을때 다른 속성값이 변경되어야 한다면 RefreshInfo 정보로 등록해 관리할 수 있습니다. 예제에서는 targetview 속성값 변경 시 targetobj 목록에 바뀌게 됩니다.

1

TestQueryAction 속성 중에서 targetview 속성을 선택한 상태에서 Refresh Properties 항목을 선택하고 [+] 버튼을 클릭한 후 [New] 항목을 선택합니다.

2

[Add Refresh Information] 창이 열리면 ID를 "targetview"로 입력하고 아래에 Refresh Item 항목에 "targetobj"를 선택해 추가합니다.

Refresh Item은 Action 오브젝트의 속성 중에서 선택할 수 있습니다.

추가한 항목은 TestQueryAction 메타인포 편집창 오른쪽 편집 아이콘을 클릭하고 Edit Common Information 창 Refresh 탭에서 확인할 수 있습니다.

Action 모듈 파일 생성하기

1

메뉴에서 [Deploy > Module Package]를 선택합니다.

2

모듈 파일을 생성할 경로를 확인하고 [Next] 버튼을 클릭합니다.

Version 등의 정보는 필요에 따라 입력합니다.

3

모듈에 포함할 대상 항목을 선택합니다.

4

[Deploy] 버튼을 클릭해 xmodule 파일을 생성합니다.