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를 설정합니다.

model 타입 서비스 등록 시 URL, ServiceList, DataSchema으로 설정한 서비스에서 Model Group, Model Service, Model 데이터를 가져올 수도 있습니다. 아래 링크를 참고하세요.

Model 서비스 조회

Model Service 항목 추가하기

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

1

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

2

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

3

TypeDefinition에서 추가한 model 타입 서비스 항목을 오른쪽 마우스로 클릭해 컨텍스트 메뉴를 실행하고 [Insert > Model Service] 항목을 선택해 Model Service를 추가합니다.

4

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

Model Wizard에서 Model 만들기

1

Model ID, Name을 입력합니다.

ID 항목값을 입력하면 Name 항목값은 자동으로 채워집니다. Name 항목값은 다른 값으로 변경할 수 있습니다.

2

Finish 버튼을 클릭하면 Wizard 창이 닫히고 Model, Model Service 설정 화면이 표시됩니다.

3

Model 설정 화면에서 추가할 속성(Field Attribute) 정보를 추가합니다.

Model 설정 화면 오른쪽 끝에 있는 [+] 버튼을 클릭하고 펼쳐지는 목록(Predefined Attribute) 중에서 'uselabel' 항목을 체크합니다.

기본 제공되는 Field Attribute는 삭제할 수 없습니다. 사용자가 추가한 Attribute와 구별할 수 있도록 라벨이 흐리게 표시됩니다.

4

Model 설정 화면 왼쪽에 있는 [+] 버튼을 클릭해 Field List 항목을 추가합니다.

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

5

메뉴에서 저장하기 아이콘을 클릭하면 설정이 저정됩니다. QuickCode 패널 Model 탭에서 Model 항목을 더블클릭하면 Model, Model Service 설정 화면을 다시 표시합니다.

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

View Template 코드 내에서 fn_GetFieldUserAttributeList 함수를 작성한 경우에는 설정된 User Attribute 목록을 가져올 수 있습니다.

1

Model 설정 화면 오른쪽 끝에 있는 [+] 버튼을 클릭하고 펼쳐지는 목록 중에서 'Add Attributes' 항목을 체크합니다.

2

Edit User Attributes 창 오른쪽 끝에 있는 설정 아이콘을 클릭하고 Add User Attribute 창을 실행합니다.

3

Target List 목록에서 User Attribute를 가져올 View Template을 선택합니다.

4

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

5

오른쪽 화살표 버튼을 클릭해 선택한 User Attribute 항목을 User Attribute List 영역에 추가합니다.

6

Add User Attribute 창에서 [OK] 버튼을 클릭하면 Edit User Attributes 창에서 추가할 항목을 확인할 수 있습니다.

7

Edit User Attributes 창에서 [OK] 버튼을 클릭하면 Model 설정 화면에 User Attribute가 추가된 것을 확인할 수 있습니다.

Model Service 설정하기

Model Service 편집 상태 시 속성창에서 Service 관련 속성을 설정할 수 있습니다. ID, Name, Url 속성값을 설정합니다.

Model 정보 소스 코드 확인하기

Model 설정 화면 하단 탭을 'Source'로 변경하면 생성된 소스 코드를 보여줍니다. 소스 코드를 직접 수정하고 하단 탭을 "Items"로 변경하면 수정된 내용을 확인할 수 있습니다.

View 템플릿 만들기

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

프로젝트 생성 시 'Use QuickCode' 항목을 체크하고 'Install > Sample'을 선택했다면 Tutorial에 사용하는 View 템플릿이 viewtemplate 폴더로 복사됩니다. View 템플릿 항목을 더블클릭하면 스크립트를 확인할 수 있습니다. 예제에서는 샘플 View 템플릿을 사용하지 않고 새로운 View 템플릿을 만듭니다.

1

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

2

Name을 입력합니다.

3

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

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

View Template 생성 시 참고할 수 있는 예시 코드를 주석 형태로 추가하고 싶지 않다면 'Include Example' 항목값을 false로 변경합니다. true로 선택한 경우에는 아래와 같이 예시 코드가 포함된 상태로 View Tamplate이 만들어집니다.

4

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

디자인 된 View 컴포넌트로 View 템플릿 만들기

View 컴포넌트 화면을 미리 디자인한 상태에서 View 템플릿을 만들 수 있습니다. View 컴포넌트 화면을 기반으로 fn_GetViewGenerationResult 함수 내 코드가 자동 생성됩니다.

1

View 컴포넌트 화면을 원하는 형태로 디자인합니다.

2

View 컴포넌트를 선택한 상태에서 메뉴[QuickCode > Design > Create View Template] 항목을 선택합니다.

3

View Template Wizard가 실행됩니다. Name, ViewType 등의 항목을 입력합니다.

4

[Finish] 버튼을 클릭하고 View 템플릿을 만듭니다. 만들어진 View 템플릿 코드에서 fn_GetViewGenerationResult 함수 내 코드가 자동 생성된 것을 확인할 수 있습니다.

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

View Template Wizard에서 View 템플릿을 만들거나 QuickCode 패널에서 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

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

넥사크로 스튜디오 설치 시 바로가기를 생성하지 않은 경우에는 설치 폴더에서 "nexacromoduledeveloper.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를 입력하면 자동으로 채워집니다. FinalClass 속성값은 true, Contents 속성값은 false로 변경합니다.

6

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

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

Action 오브젝트 추가하기

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

1

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

2

Object ID를 입력합니다.

추가하는 Action 오브젝트의 이름은 "TestAlertAction"입니다. FinalClass 속성값은 true, Contents 속성값은 false로 변경합니다.

3

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

Action 오브젝트 속성 편집하기

1

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

subgroup: Action
registration: allow

2

변경 사항을 저장합니다.

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.destroy = function ()
	{
		nexacro.Action.prototype.destroy.call(this);
        this.samplefilename = null;
		this.alerttype = 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._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 오브젝트는 아래와 같이 2개의 속성을 추가합니다.

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 모듈 파일 생성하기

1

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

2

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

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

3

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