-
Notifications
You must be signed in to change notification settings - Fork 0
video02_concepts
#VIDEO 02. [Concepts] Intro to List Component
원문 : http://docs.sencha.com/touch/2-0/#!/video/list
번역 : https://github.com/KoreaSenchaUserGroup/Lab1/wiki/video02_concepts
글쓴이 : 이민호 (Github:tisohjung), 한국센차유저그룹 SenchaCon 번역팀
#The List Component
Sencha Touch provides a list component which is ideal for presenting a index style list of items. In this tutorial we'll setup a basic list, then how to add an index bar and regroup the items together under marker. Finally we'll see how to reveal a detail panel which could show additional information about each item in the list.
센차 터치는 인덱스 스타일의 리스트 아이템에 적합한 리스트 컴포넨트를 지원합니다. 이번 강좌에서는 간단한 리스트들 만들고 인덱스바와 마커 아래 리그룹하는 방법등을 보겠습니다. 마지막으로 리스트 안에 추가적인 아이템의 정보를 볼수있는 디테일 패널을 보겠습니다
00:25 Configure a basic list
Let's start by making a list component. In the view's directory we'll create a new file called PresidentList.js. We'll define a PresidentList class, taken care to spell it the same way as the file name. And we'll make it extend from the list component. We're not done just yet, we'll need to setup a couple of configuration options, but we'll come back and do that later. To populate the list with some data, we have to bind it with the data store.
우선은 리스트 컴포넨트를 만들어보겠습니다. view폴더 안에 PresidentList.js 라는 마일을 새로 만들겠습니다. PresidentList 클래스를 정의하겠습니다, 파일 이름과 다르지 않게 주합니다. 그리고 list 컴포넨트를 상속받도록 하겠습니다. 아직 끝나지 않았습니다, 몇가지 환경 설정을 해야되지만 잠시후 다시 돌아와서 하겠습니다. 리스트를 데이터로 채우기 위해, 데이터 저장소와 연결해야합니다.
We'll create a new file under store directory called Presidents.js. Here we define a president class which extends from the store class. We also have to define the fields of an individual record. In the model directory we'll create a new file called President.js. Here we'll define a President class which extends from the model class. In the config object we specify 3 fields firstname, middleInitial, and lastName. That's all we need to do for the model for now.
store 폴더 안에 President.js 라는 새 파일을 만듭니다. 여기에 Store클래스를 상속받는 president 클래스를 정의합니다. 또한 각각의 기록의 필드를 정의해야합니다. model 폴더에 President.js 파일을 생성합니다. 여기에 Model클래스를 상속받는 President 클래스를 정의합니다. config 객체에 3가지 ['firstName', 'middleInitial', 'lastName']을 명시합니다. 일단 모델은 끝입니다.
Let's switch back to the store and configure it so it loads a collection of president records. We could configure the store with a proxy, so that it fetches record from a server, or from local storage. But we'll keep things simple here, and define the data inline. Note that the fields of each item in the data list, correspond to those we set up in the module.
다시 store로 돌아가서 president 기록을 가져오게 설정합니다. 프록시로 설정해서 서버에서 기록을 가져오게 할수도, 로컬저장소에서 가져오게 할수도 있습니다. 하지만 간단하게 데이터 인라인으로 정의하겠습니다. 데이터 리스트의 각각의 필드가 모듈에 설정한것과 일치하는것을 볼 수 있습니다.
Now that we've setup the module and the store, we can bind them to list component. We'll configure our president list so that it references the presidents store. We also have to tell our component how to represent each item in the list. We'll simply show the firstName, and the lastName in the itemTpl. Now lets switch to the app.js file. We want to create an instance of the presidentList class when the application launches. We can do so by adding our custom component to the viewport inside the launch function. We also need to list each of our custom classes as a requirement for the application. We can reference them as the models, stores and views objects. Now if we take a look in the browser, we should find a vanilla version of the list view.
이제 모듈과 저장소를 설정했으니, 리스트 컴포넨트와 연결시켜보겠습니다. PresidentList를 설정해 Presidents 저장소를 참조하게 하겠습니다. 또한 컴포넨트가 각각의 리스트에 있는 아이템들을 어떻게 보여줄지 알려줍니다. 간단히 itemTpl에서 firstName과 lastName을 보여주도록 하겠습니다. 자이제 app.js 파일로 가겠습니다. 어플리케이션이 켜지면 presidentList 클래스의 인스턴스를 만들고싶습니다. 그러기 위해서 우리가만든 커스텀 컴포넨트를 launch함수의 Viewport안에 넣습니다. 또한 어플리케이션의 필수요소로 각각의 커스텀 클래스를 나열합니다. models, stores와 views 객체로 참조 할 수 있습니다. 이제 브라우져에서 보면, vanilla version의 리스트뷰를 볼수있습니다(읭 바닐라버젼? 초간단 프로토타입 같은걸 말하는듯? 아니면 귀구녕이 이상하거나;;;).
03:06 Group records by lastName and add an indexBar
The list class includes a configuration property called grouped. It's false by default, but if we set it to true, we can group the items in a list together. When grouped is set to true it is a requirement that the store associated with the list, implements the function called grouper. In this case we want to make this method return the first letter of the lastName field. At the moment the names are listed in the order which they were created. If we're going to group together the lastNames with the same initial letter, then we should also sort the list by the last name. When we refresh the browser, you'll see that the names are grouped together by last name. The list also includes a property called indexBar. Setting this to true, adds an index to the list view, making it easy to jump to a letter group.
리스트 클래스는 grouped라는 설정 변수를 포함합니다. 디폴트값은 false입니다, 하지만 true로 바꾸면 리스트에있는 아이템을 그룹화 할 수 있습니다. grouped가 true값일때 리스트와 연결되있는 저장소(store)가 grouper함수를 포함해야합니다. 여기에서는 lastName 필드의 첫번째 문자를 반환하게 하겠습니다. 현재는 리스트의 이름이 만들어진 순으로 출력이 됩니다. 만일 여기서 lastName들을 알파벳별로 그룹시키려면 lastName을 알파벳 정렬해야합니다. 브라우져를 새로고치면 이름이 lastName순으로 그룹정렬되있는 것을 볼 수 있습니다. 리스트는 indexBar라는 속성도 가지고있습니다. 이것에 true값을 주면 리스트뷰에 인덱스를 보여줍니다. 이제 그룹찾기 참 쉽죠?
04:05 Show a detail view
So far we have a nice looking list. But wouldn't it be more useful if we can use a detail panel for each item? We'll start by defining a function on the list view called onItemDisclosure. For now we'll just make it log a message to the console. If we test it in the browser we'll see that each list item now has a disclosure icon. When tapped, a message appears on the console. Rather then handling the disclosure event inside of the view, we're going to do it in the controller. So let's replace the function with a boolean value of true. This simply tells the view to include a disclosure icon without specifying its' behavior.
현재상태로도 리스트가 보기 좋습니다. 하지만 디테일패널이(우측에클릭표시) 있으면 더 좋겠죠? 우선 onItemDisclosure이라는 함수를 디테일 뷰에 정의해주겠습니다. 일단은 콘솔에 메세지 출력만 하게 해두겠습니다. 브라우져에서 실험해보면, 각각의 리스트 아이템들이 디스클로져 아이콘을 띄고 있습니다. 눌러보시면, 콘솔에 메세지가 출력됩니다. 디스클로져 이벤트를 뷰안에 처리해주는 대신 컨트롤러 안에다 하겠습니다. 일단 함수를 Boolean 변수로 true로 바꾸겠습니다. 이것은 간단히 디스클로져아이콘을 추가만 해주고 무엇을 할지는 정의하지 않습니다.
We'll implement the disclosure handler soon. But first let's consider what we've got in our application right now. The view port contains a single list component which currently occupies the full screen. We're going to have to add a second component for the detail view, as well as a container with a card layout to manage the 2 views. In this case we'll use the navigation review component as our container. When the application launches, the navigation view will only contain a single card, our list. But when the user taps a disclosure icon, we'll create a new detail view and push it onto the container.
디스클로져 핸들러는 잠시후 다시 정의하겠습니다. 일단은 어플리케이션에 뭐가있는지 한번 보겠습니다. 뷰포트는 현재 전체화면을 차지하고있는 하나의 리스트 컴포넨트를 포함하고있습니다. 이제 디테일뷰를 위해서 두번째 컴포넌트를 추가해야됩니다. 또한 두개의 뷰를 관리하기위한 카드레이아웃이 있는 컨테이너가 필요합니다. 여기서는 네비게이션뷰 컴포넌트를 컨테이너로 쓰겠습니다. 앱이 실행되면 네비게이션뷰는 한개의 카드만을 갖고있습니다, 하지만 디스클로져 아이콘을 클릭하게 되면, 새로운 디테일뷰를 컨테이너로 푸쉬(얹혀줌) 해줍니다.(스택형태의 뷰 관리)
The navigation view automatically adds a tool bar with a back button. When pressed the back button pops the top most view from the stack, revealing the list again. Let's start by defining a detail view. We'll create a new file in the view's directory called PresidentDetail. This extends the panel class. Later on we'll set the title and html properties dynamically. But for now, we'll just use couple of place holder values.
네비게이션뷰는 자동으로 툴바에 뒤로가기 버튼을 만들어줍니다. 누르면 스택에서 최상위의 뷰를 팝(빼줌)해주며 리스트로 돌아갑니다. 우선 디테일뷰를 정의해주겠습니다. PresidentDetail 폴더에 새로운 파일을 생성합니다. 패널 클래스를 상속해줍니다. 나중에 title과 html 변수를 동적으로 만들어주겠습니다. 하지만 일단은 대체적인 값을 넣어두겠습니다.
Next we'll create the navigation view. We've already got a file here called "Main.js", so let's use that. We'll change it from Ext.Panel into a navigation.View. Since this view is going to act as a container our list and detail cards, we have to specify these as requirements. When this class is instantiated we want it to contain a single item, a presidentlist. Here we're using the xtype which is a short hand for referencing classes. Let's make sure we've declared an xtype for each of our custom components. We'll call this main class mainpanel. The list panel can be referenced by presidentlist, and the detail panel can be referenced as presidentdetail.
다음은 네비게이션뷰를 만들어보겠습니다. 이미 있는 Main.js 라는 파일을 사용하겠습니다. Ext.Panel을 navigation.View로 바꿔주겠습니다. 이뷰는 리스트와 티테일카드들의 컨테이너 역할을 할것이기 때문에, requirements(requires:)를 정의해줘야합니다. 이 클래스가 초기화되면 presidentlist라는 하나의 아이템을 포함하고있길 원합니다. 여기서는 참조 클래스를 말하는 xtype을 사용합니다. 각각의 커스텀 컴포넌트에 xtype을 선언했는지 주의하시길 바랍니다. 이 메인 클래스를 mainpanel이라고 이름짓겠습니다. 리스트 패널은 presidentlist로 참조하고 리스트패널은 presidentdetail로 참조 할 수 있게 하겠습니다.
Now we'll switch to app.js file. Right now we are adding a presidentList to the view port. Let's change this by adding a main panel instead. We also have to update the views requirement to reference the main view. Now let's see what this looks like in the browser. It's almost the same as before except this tool bar. If we give our list component a title, then it will appear in the toolbar like so. Now all we have to do is wire up the handler for these disclosure buttons. Let's open up our main controller. This is where we'll add logic for handling the onItemDisclosure event. Inside of our control object, we'll add a reference to the presidentlist component. We want to trigger a function when the disclose event is captured by this component. For now we'll just log a message to the console. Let's check it in the browser to see if it works. Yes, clicking the disclosure icon logs a message, as expected.
app.js파일을 열어보겠습니다. 현재는 뷰포트에 presidentList를 추가해놨습니다. 이것을 Main 패널로 바꿔주겠습니다. 또한 views를 Main 뷰를 참조하게 바꿔줘야합니다. 이제 브라우져를 한번 보겠습니다. 아까전과 거의 비슷한데 위에 툴바가 생겼습니다. 리스트컴포넌트에 title을 주면 툴바에 보여지게됩니다. 이제 디스클로져버튼에 핸들러만 만들어주면 됩니다. 메인컨트롤러를 열어보겠습니다. 여기에 onItemDisclosure 이벤트 핸들러를 추가하겠습니다. control 객체에 presidentlist 컴포넌트 상속을 추가하겠습니다. diclose 이벤트가 들어오면 실행하는 함수를 만들겠습니다. 일단은 콘솔에 메시지 출력으로 해두겠습니다. 브라우져로 돌아가서 잘 돌아가는지 확인하겠습니다. 예스 예상대로 디스클로져 아이콘 클릭하니 메세지 출력이되네요 잘되네요 난최고야(읭?).
Rather then defining an anonymous function inline, let's create a function called showDetail. We'll call this when the presidentlist disclose event fires. The implement is quite simple. We want to fetch reference to the navigation view, and push onto it, a new detail panel. To make this work, we first have to define the getMain function. When the application launches it automatically creates a getter function for each key defined in the refs configuration. So if we create a key called main, sencha touch will give us a getmain function for free. We don't have to implement function, we only need to provide component query selector. In this case the xtype mainpanel will do the job. Let's have a look at this in the browser. When we click a load disclosure icon it shows a panel with "Hello, World!" text.
임의의 함수를 정의해주는 대신 showDetail이란 함수를 만들어주겠습니다. 이 함수를 presidentlist의 disclose이벤트가 발생하면 불르겠습니다. 실행하는것은 간단합니다. 네비게이션뷰의 참조를 가져와서 새로운 디테일 패널을 푸쉬해줍니다. 이게 돌아가게 하려면 우선은 getMain 함수를 정의해줘야합니다. 앱이 실행되면 refs 설정의 각각의 키에 대해 getter 함수가 자동으로 만들어집니다. 그래서 main이라는 키를 만들면, 센차 터치가 자동으로 getMain 함수를 만들어줍니다. 함수를 따로 구현할 필요없이, 컴포넌트 쿼리 셀렉터만 주면 됩니다. 여기서는 xtype mainpanel 이 해줍니다. 브라우져에서 한번 보겠습니다. 디스클로져 아이콘을 클릭하면 "Hello, World!"라고 쓰여진 패널이 뜹니다.
Note that the navigation view has automatically added a back button. Which let's a step back to the list view. Next we want to customize the detail panel, so that it shows the information about the record that was disclosed. Let's start by looking up the documentation for the disclose event. The function signature contains 6 arguments. But the only one we are going to actually need is this one, the record. We'll add the first 2 argument to the showDetail function. Now when we instantiate the new detail card, we can pass the record data along with it. Let's switch to the detail panel and change the text. Instead of using "Hello, World!" as static html, we'll switch to an xtemplate and use the first name field in the greeting. This place holder will be replaced with data from the selected record. Check it out in the browser. When we click on the disclosure icon, we get a message customized for that record. There's one final customization we should make. Instead of having a title that says details, let's update that dynamically as well. In our president model, we can create a function called fullName. This includes the middleInitial, but only if one is given. Now in our disclosure handler, we can call this function using the return values to set the title of our detail card. Check it out in the browser and we should see a customized title, each time we disclose the detail panel for the record.
네이게이션 뷰가 자동으로 뒤로가기 버튼을 만들어준걸 볼 수 있습니다. 클릭하면 다시 리스트뷰로 돌아갑니다. 다음은 디테일 패널을 어떤 자료를 통해 들어왔는지 보여주게 커스터마이즈하고싶습니다. 우선 도큐먼트에 disclose 이벤트에 대해 찾아보겠습니다. 함수정의에는 6개의 값이 들어있습니다, 그중 필한것은 record하나면 됩니다. 제일 위의 두개 값을 showDetail함수가 받게 하겠습니다. 이제 디테일 카드를 초기화시에 데이터값을 가져올수 있습니다. 디테일 패널로 돌아가서 텍스트를 바꿔보겠습니다. Hello, World 대신 xtemplate를 사용해서 이름필드 값을 출력해보겠습니다. 이 플레이스홀더는 앞의 데이터에서 선택한 레코드로 대체됩니다. 마지막으로 한가지 더 해야됩니다. 타이틀에 details라고 표기되는 대신 이것도 동적으로 바꾸겠습니다. President에 Model에서 fullName이라는 함수를 만들겠습니다. middleInitial이 있을시에만 표기되게 했습니다. 이제 디스클로져 핸들러에서, 앞의 함수를 불러 리턴되는 값으로 title을 설정합니다. 체킷아웃 브라우져 크스터마이즈 타이틀 디스클로즈 버튼누를때마다 바뀝니다.
11:00 Outro
The code used in this demonstration can be found on the github. I've created a separate branch for every check point. So each time you see a card like this one, it means that you can checkout a snapshot of the code. In it comes the state at that point in the screen cast. You can find instructions on how to view these snapshots in the repository's readme file. github에 브랜치로 나눠서 영상에서 아래 거므티티한 주석뜨면 다 찾아볼 수 있답니다 readme파일에 안내문서랑 다 들어있답니다 자세한 번역은 생략합니다.