퓨즈[Fusetools] 문서[Docs] 번역

  1. Home
  2. 퓨즈[Fusetools] 문서[Docs] 번역
  3. 튜토리얼
  4. 1. 하이킹(Hike) 편집 화면

1. 하이킹(Hike) 편집 화면

소개

이 튜토리얼의 처음 파트에서는 우리 앱의 첫 번째 뷰(‘하이킹(Hike) 편집 화면’)를 구체화할 것입니다. 이 뷰는 하이킹 리스트 중 하나의 데이터를 표시하고 편집할 수 있게 합니다. 즉, 상호 작용할 비주얼 컴포넌트를 보여주는 뷰와 편집 가능한 데이터를 보여주는 뷰 모델을 빌드하게 됩니다.

이 챕터의 최종 코드는 여기에 있습니다.

프로젝트 만들기

우리가 할 첫 번째 일은 프로젝트를 만드는 것입니다. 우리는 그걸 “hikr”라 부르죠. 퀵스타트와 마찬가지로 퓨즈 대시보드 또는 커맨드라인 툴을 이용해서 작업할 수 있습니다. 예를 들면:

1
fuse create app hikr [optional path]

이렇게 하면 다음과 같은 디렉터리 구조가 생성됩니다:

1
2
3
4
$ tree
.
|- MainView.ux
|- hikr.unoproj

이 두 개의 파일이 퓨즈 앱을 구동하기 위한 모든 것입니다! ‘MainView.ux’는 앱의 최상위 뷰를 위한 UX 코드가 포함되어 있고, ‘hikr.unoproj’는 다양한 프로젝트 설정이 들어 있습니다. 이 챕터에서 다룰 내용은 모두 ‘MainView.ux’에 대한 것입니다.

이제 프로젝트를 만들었으니 디렉토리에 들어가서 프리뷰를 시작할 것입니다. 물론, 대시보드 또는 커맨드라인 툴로 실행할 수 있습니다:

1
2
cd hikr
fuse preview

실제 디바이스에서 프리뷰를 시작할 수도 있습니다. 지금 해보는 것도 좋을 것 같네요. 실행 방법에 대한 정보를 얻고 싶다면 프리뷰 및 내보내기 가이드를 참조하세요.

첫 번째 하이킹 보여주기

이제 프로젝트를 만들었고 프리뷰도 띄웠으니 데이터 표시를 시작하고 데이터 모델을 구현해야 할 때입니다. 다른 페이지를 설정하는 것에 대한건 잊어버리세요. 지금은 단순히 텍스트를 보여주는 것부터 시작할 것입니다.

‘MainView.ux’를 열면, 다음과 같이 보일 것입니다:

1
2
<App>
</App>

보셨다시피, 깨끗하게 비어있는 App 태그 뿐입니다. UX에서 태그는 대소문자를 구분합니다. 예를 들어, App은 app과 다릅니다.

이제 기본 Text 요소(element)를 추가하겠습니다:

1
2
3
<App>
    <Text>Tricky Trails</Text>
</App>

이 시점에서, ‘MainView.ux’를 저장해보죠. 그러면 띄워진 모든 프리뷰 화면들이 업데이트될 것입니다! 퓨즈로 작업할 때, 자주 저장하는 것이 좋습니다. 그러면 에러나 오타가 쌓이기 전에 바로바로 잡아낼 수 있기 때문입니다.

위에서 본 것처럼, Text는 텍스트의 읽기 전용 블럭(수정할 수 없는)을 표시할 때 사용합니다. 이것은 데스크탑에서는 문제가 없지만, 사용자가 디바이스에서 프리뷰를 보고 있다면 상태바에 가려졌을 것입니다. 이를 해결하기 위해, ‘ClientPanel’ 태그로 감싸겠습니다:

1
2
3
4
5
<App>
    <ClientPanel>
        <Text>Tricky Trails</Text>
    </ClientPanel>
</App>

‘ClientPanel’은 뷰를 위해 정의된, 각각의 다양한 OS가 제공하는 화면 상단과 하단의 공간을 확보하는 컨테이너이며, 우리가 원하는대로 잘 작동할 것입니다.

계속하기 전에 StackPanel 내부에 Text 요소를 배치해 보겠습니다. StackPanel은 자식 요소들을 세로 또는 가로로 순서대로 쌓는 컨테이너입니다. 우리는 객체가 하나뿐이므로 확인이 어렵겠지만, 나중을 위해 지금 만들어 두면 좋을 것입니다. 코드는 매우 간단합니다:

1
2
3
4
5
6
7
<App>
    <ClientPanel>
        <StackPanel>
            <Text>Tricky Trails</Text>
        </StackPanel>
    </ClientPanel>
</App>

뷰 모델과 데이터 바인딩

좋습니다! 화면에 텍스트가 표시되었네요. 하지만, 그건 UX에 문자열을 하드코딩한거라 맘에 들진 않네요. 왜냐하면 앞으로 하이킹의 개별 아이템을 동적으로 보여주고 수정해야 하니까요. 이 텍스트가 뷰 모델의 자바스크립트로 구현되는 부분이며, 이제 데이터 바인딩을 이용해서 모두 연결할 것입니다.

hike의 이름을 내보내기 위한(module.exports) 인라인 자바스크립트를 추가합시다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<App>
    <ClientPanel>
        <JavaScript>
            var name = "Tricky Trails";

            module.exports = {
                name: name
            };
        </JavaScript>

        <StackPanel>
            <Text>Tricky Trails</Text>
        </StackPanel>
    </ClientPanel>
</App>

UX에서 값을 가져올 수 있지만 여전히 하드코딩된 값을 쓰고 있네요. Text의 요소를 변경해 보겠습니다.

1
<Text Value="{name}" />

멋집니다! 하이킹 중 하나의 이름을 동적으로 표시했습니다. 이것은 JS에서 UX로 이동하는 단방향 데이터 바인딩을 보여줍니다. 이것은 데이터를 표시하기에는 충분하지만 편집은 할 수 없습니다. 좀 더 진행해 보시죠.

옵저버블(Observables)과 양방향 데이터 바인딩

우리가 할 일은 UI에 TextBox를 추가하는 것입니다. TextBox는 일반적인 스타일의 간단한 단일 행 텍스트 입력 필드를 나타내며, 우리는 이름을 편집하는데 사용할 것입니다. 하지만 먼저 TextBox의 값이 수정될 때 다른 UI에 변경사항을 알릴 수 있어야 합니다. 즉, 변수가 변경되는걸 관찰할 수 있어야 합니다. 이를 위해, FuseJS의 Observable이 사용됩니다.

이것이 어떻게 작동하는지 확인하기 위해, 먼저 FuseJS의 Observable 모듈을 가져옵니다. JS 코드를 상단에 추가하세요:

1
var Observable = require("FuseJS/Observable");

이제 name 변수의 선언을 다음과 같이 변경하세요:

1
var name = Observable("Tricky Trails");

이제, name은 일반 변수가 아닌 Observable입니다. 즉, UI 또는 해당 Observable을 접근할 수 있는 다른 코드가 이를 변경할 수 있습니다. Observable에 데이터 바인딩을 하면, Fuse가 값을 변경할 때마다 UI가 업데이트 되도록 모든 처리를 정확하게 수행합니다. 굉장하죠!

물론, 이제 우리는 이 값을 변경할 뭔가가 실제로 필요합니다. 이제 TextBox를 추가해 보겠습니다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<App>
    <ClientPanel>
        <JavaScript>
            var Observable = require("FuseJS/Observable");

            var name = Observable("Tricky Trails");

            module.exports = {
                name: name
            };
        </JavaScript>

        <StackPanel>
            <Text Value="{name}" />

            <TextBox Value="{name}" />
        </StackPanel>
    </ClientPanel>
</App>

이제 파일을 저장할 때마다 Text와 TextBox에 name 옵저버블의 값이 표시됩니다. 그리고 TextBox의 내용을 수정하면 Text 값도 변경되는걸 볼 수 있습니다! 이것은 TextBox의 value 속성에 대한 데이터 바인딩이 양방향을 지원하기 때문입니다. 즉, 자동으로 값이 들어오기도 하고 변경되기도 합니다.

Text를 캡션으로 변경하겠습니다:

1
2
<Text>Name:</Text>
<TextBox Value="{name}" />

좋아졌네요!

필드 추가하기

편집 페이지가 생겼으니 우리가 관심있는 다른 필드를 포함시키기 위해 모델을 살펴보겠습니다. 하이킹은 다음 필드가 필요합니다.

  • name (which we’ve already got covered)
  • location
  • distance (km)
  • rating (1-5)
  • comments

뷰 모델을 단순하게 유지하기 위해, 다른 Observable들을 생성하겠습니다. 그리고 편집을 위해 TextBox를 사용합니다. 우선 아래와 같이 Observable들을 만드시죠:

1
2
3
4
5
var name = Observable("Tricky Trails");
var location = Observable("Lakebed, Utah");
var distance = Observable(10.4);
var rating = Observable(4);
var comments = Observable("This hike was nice and hike-like. Glad I didn't bring a bike.");

그리고 JS 모듈에 추가합니다:

1
2
3
4
5
name: name,
location: location,
distance: distance,
rating: rating,
comments: comments

마지막으로, Observable에 바인딩할 TextBox를 추가합니다. (캡션과 함께):

1
2
3
4
5
6
7
8
9
10
11
<Text>Location:</Text>
<TextBox Value="{location}" />

<Text>Distance (km):</Text>
<TextBox Value="{distance}" InputHint="Decimal" />

<Text>Rating:</Text>
<TextBox Value="{rating}" InputHint="Integer" />

<Text>Comments:</Text>
<TextBox Value="{comments}" />

숫자 데이터 입력을 위해 TextBox의 InputHint를 추가한 것을 알 수 있습니다. 이렇게 하면 iOS 및 Android에서 이 필드를 수정할 때 숫자 키보드가 표시됩니다.

마지막으로 좀 더 손보기

여기까지 잘 따라왔다면, 완벽하게 동작하는 편집 화면이 만들어져 있을 것입니다. 멋집니다! 이제 몇 가지만 더 개선시켜 보시죠.

주석(comments) 입력 필드를 살펴보겠습니다:

텍스트가 너무 길어서 보기에 좋지 않습니다. 텍스트를 잘 볼 수 있도록 여러줄로 표시되도록 하면 훨씬 더 좋을 것입니다.

이 문제를 해결하기 위해 TextBox를 사용하는 대신 TextView를 사용하고 TextWrapping 속성을 Wrap으로 설정하세요:

1
2
<Text>Comments:</Text>
<TextView Value="{comments}" TextWrapping="Wrap" />

여러줄을 표시하는 편집기가 완성되었습니다. 물론, 아주 멋지지는 않습니다. 나중에 스타일링에 대해 설명하겠습니다. 지금은 앱의 중요한 부분에 집중하는게 좋을 것 같네요.

마지막으로 할 것은 요소들이 너무 많아서 화면 바깥으로 벗어나는 경우를 대비해 StackPanel을 ScrollView 안에 배치하는 것입니다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<ScrollView>
    <StackPanel>
        <Text Value="{name}" />

        <Text>Name:</Text>
        <TextBox Value="{name}" />

        <Text>Location:</Text>
        <TextBox Value="{location}" />

        <Text>Distance (km):</Text>
        <TextBox Value="{distance}" InputHint="Decimal" />

        <Text>Rating:</Text>
        <TextBox Value="{rating}" InputHint="Integer" />

        <Text>Comments:</Text>
        <TextView Value="{comments}" TextWrapping="Wrap" />
    </StackPanel>
</ScrollView>

이제 우리가 원하는 필드를 편집하기 위해 폼을 위/아래로 스크롤할 수 있습니다. 멋집니다!

우리의 진행 상황

이 시점에, 우리는 하이킹 데이터를 표시 및 편집할 수 있는 뷰를 가지고 있습니다. 그것은 다음과 같이 보입니다:

그리고 전체 코드는 다음과 같습니다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<App>
    <ClientPanel>
        <JavaScript>
            var Observable = require("FuseJS/Observable");

            var name = Observable("Tricky Trails");
            var location = Observable("Lakebed, Utah");
            var distance = Observable(10.4);
            var rating = Observable(4);
            var comments = Observable("This hike was nice and hike-like. Glad I didn't bring a bike.");

            module.exports = {
                name: name,
                location: location,
                distance: distance,
                rating: rating,
                comments: comments
            };
        </JavaScript>

        <ScrollView>
            <StackPanel>
                <Text Value="{name}" />

                <Text>Name:</Text>
                <TextBox Value="{name}" />

                <Text>Location:</Text>
                <TextBox Value="{location}" />

                <Text>Distance (km):</Text>
                <TextBox Value="{distance}" InputHint="Decimal" />

                <Text>Rating:</Text>
                <TextBox Value="{rating}" InputHint="Integer" />

                <Text>Comments:</Text>
                <TextView Value="{comments}" TextWrapping="Wrap" />
            </StackPanel>
        </ScrollView>
    </ClientPanel>
</App>

우리가 볼 수 있듯이, 이런 뷰를 만들어서 작동시키는 것은 그리 많은 노력이 들지 않습니다. 우리는 다음과 같은 것들을 다뤘습니다:

  • 프로젝트 생성 / 미리보기 / 수정하기
  • Observables 및 데이터 바인딩 사용
  • 뷰 및 뷰 모델 작성

다음으로 진행할 일

위 화면은 하나의 하이킹을 표시합니다. 하지만 우리는 하이킹 리스트 전체를 표시하고 수정하는게 목표입니다. 다음 챕터에서는 여러가지 하이킹을 소개하고 표시 및 편집할 수 있는 기능으로 확장할 것입니다. 준비가 되었다면 뛰어들어 봅시다!

최종 코드는 여기에 있습니다.

Was this article helpful to you? Yes 1 No

How can we help?