I 최근에 쓴 Angular로 빌드된 NativeScript iOS 및 Android 애플리케이션에서 Couchbase를 키-값 저장소로 사용하는 예제입니다. 이 예제에서는 다음에서 저장하거나 로드할 사용자 프로필 정보를 수집하는 방법을 살펴봤습니다. 카우치베이스 를 사용했습니다. 하지만 문서 속성을 기반으로 쿼리하는 것이 아니라 특정 키를 기반으로 저장 및 로드하고 있었습니다.
키를 모르고 문서 속성을 기반으로 쿼리해야 하는 NoSQL 문서가 있다면 어떻게 해야 할까요? 이 예제에서는 문서 속성을 기반으로 쿼리해야 하는 이전 기사 를 한 단계 업그레이드하세요.

단일 페이지를 가져올 것입니다. 네이티브 스크립트 애플리케이션을 여러 페이지로 확장하면 첫 번째 페이지에는 이전에 저장한 프로필 목록이 표시되고 두 번째 페이지에서는 새 프로필을 만들 수 있습니다. 페이지 간 탐색은 앵귤러 라우터를 통해 이루어집니다.
요구 사항
이 가이드와 이전 가이드의 요구 사항은 동일하게 유지됩니다. 다음이 필요합니다:
- 네이티브스크립트 CLI 2.0+
- Mac용 Android SDK 및/또는 Xcode
노드 패키지 관리자(NPM)를 통해 얻은 네이티브스크립트 CLI를 사용하면 모바일 프로젝트를 생성하고 빌드할 수 있습니다. 실제 Android 및 iOS 애플리케이션을 빌드하고 배포하려면 Android SDK 또는 Xcode 또는 둘 다 필요합니다.
중단한 부분부터 다시 시작하기
프로젝트를 처음부터 새로 구축하는 것이 아니라 대신 이전 카우치베이스와 네이티브스크립트 튜토리얼. 그러나 여기에 표시되는 대부분의 내용은 리뷰입니다.
이전 프로젝트는 기본 한 페이지짜리 애플리케이션이어야 하며 네이티브 스크립트 카우치베이스 플러그인을 설치했습니다. 단일 페이지를 여러 페이지로 가져와야 합니다.
탐색을 위한 여러 애플리케이션 페이지 준비
이전에 만든 모달에 추가로 두 페이지를 사용할 것입니다. 프로젝트 내에서 다음 파일과 디렉터리를 만듭니다:
|
1 2 3 4 5 6 |
app/components/profile-list/ app/components/profile-list/profile-list.ts app/components/profile-list/profile-list.html app/components/profile/ app/components/profile/profile.ts app/components/profile/profile.html |
위의 파일은 두 페이지를 나타냅니다. 앵귤러 라우터를 성공적으로 사용하려면 이 파일들을 서로 연결하는 라우팅 파일을 만들어야 합니다.
프로젝트 내에서 다음을 생성합니다:
|
1 |
app/app.routing.ts |
아직 페이지 클래스를 만들지는 않았지만 서로 연결하는 데 집중하겠습니다. 프로젝트의 앱/앱.라우팅.ts 파일을 열고 다음을 포함하세요:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import { ProfileListComponent } from "./components/profile-list/profile-list"; import { ProfileComponent } from "./components/profile/profile"; export const appRoutes: any = [ { path: "", component: ProfileListComponent }, { path: "profile", component: ProfileComponent } ]; export const appComponents: any = [ ProfileListComponent, ProfileComponent ]; |
짐작할 수 있듯이 우리는 프로필 목록 구성 요소 및 프로필 컴포넌트. 에 관해서는 앱 경로를 클릭하면 기본 페이지는 경로 경로가 비어 있는 페이지입니다. 두 번째 페이지는 탐색할 때 프로필 경로.
각 컴포넌트를 배열에 추가하면 다음 단계에서 편리하게 사용할 수 있습니다.
프로젝트의 앱/앱.모듈.ts 파일을 사용하도록 라우터를 구성해야 하므로 방금 생성한 라우팅 파일을 사용해야 합니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core"; import { NativeScriptModule } from "nativescript-angular/platform"; import { NativeScriptFormsModule } from "nativescript-angular/forms"; import { NativeScriptRouterModule } from "nativescript-angular/router"; import { ModalDialogService } from "nativescript-angular/modal-dialog"; import { appComponents, appRoutes } from "./app.routing"; import { AppComponent } from "./app.component"; import { ModalComponent } from "./app.modal"; @NgModule({ declarations: [AppComponent, ModalComponent, ...appComponents], entryComponents: [ModalComponent], bootstrap: [AppComponent], imports: [ NativeScriptModule, NativeScriptFormsModule, NativeScriptRouterModule, NativeScriptRouterModule.forRoot(appRoutes) ], providers: [ModalDialogService], schemas: [NO_ERRORS_SCHEMA] }) export class AppModule { } |
위에서는 이전 튜토리얼의 모든 모달 관련 항목이 여전히 남아 있음을 알 수 있습니다. 이번에는 이전 튜토리얼의 앱/앱.라우팅.ts 파일에 삽입하고 수입 그리고 선언 배열의 @NgModule 블록.
라우팅 시스템의 상위 페이지는 앱 컴포넌트 클래스를 삭제해야 합니다. 이를 지워야 합니다.
프로젝트의 app/app.component.html 파일을 열고 다음 XML 마크업을 포함합니다:
|
1 |
이와 페어링하기 위해 다음과 같이 대부분의 코드를 제거할 수 있습니다. app/app.component.ts 파일을 만듭니다. 이 파일의 최종 모습은 다음과 비슷해야 합니다:
|
1 2 3 4 5 6 7 |
import { Component } from "@angular/core"; @Component({ selector: "my-app", templateUrl: "app.component.html", }) export class AppComponent { } |
이 시점에서 각 애플리케이션 페이지 개발을 시작할 수 있습니다. 앵귤러 라우터를 사용한 라우팅에 대한 자세한 내용은 이전 기사 이 주제에 대해 글을 썼습니다.
이전 카우치베이스 네이티브스크립트 예제에서 코드 옮기기
방금 지우라고 말씀드린 코드를 기억하시나요? 그런 말을 하면 안 되겠지만 다행히도 이전 예제에서 복사하여 붙여넣을 수 있으며, 더 나은 방법은 아래를 참조하세요.
우리는 이전에 코드의 app/app.component.ts 그리고 app/app.component.html 파일로 이동하고 새 앱/컴포넌트/프로필/프로필.ts 그리고 앱/컴포넌트/프로필/프로필.html 파일.
열기 앱/컴포넌트/프로필/프로필.html 파일을 열고 다음과 같이 만듭니다:
|
1 2 3 4 5 |
<label class="label"></label> <label class="label"></label> <button class="btn btn-primary w-full"></button> |
위에서 변경된 유일한 사항은 데이터를 로드하는 데 사용되던 작업 표시줄의 버튼을 제거한 것입니다. 이제 프로젝트의 앱/컴포넌트/프로필/프로필.ts 파일을 열고 다음을 포함하세요:
|
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 |
import { Component, ViewContainerRef } from "@angular/core"; import { Location } from "@angular/common"; import { ModalDialogService } from "nativescript-angular/directives/dialogs"; import { Couchbase } from "nativescript-couchbase"; import { ModalComponent } from "../../app.modal"; @Component({ selector: "profile", templateUrl: "./components/profile/profile.html", }) export class ProfileComponent { public profile: any; private database: any; public constructor(private modal: ModalDialogService, private vcRef: ViewContainerRef, private location: Location) { this.profile = { photo: "~/kitten1.jpg", firstname: "", lastname: "" } this.database = new Couchbase("data"); } public showModal(fullscreen: boolean) { let options = { context: { promptMsg: "Pick your avatar!" }, fullscreen: fullscreen, viewContainerRef: this.vcRef }; this.modal.showModal(ModalComponent, options).then((res: string) => { this.profile.photo = res || "~/kitten1.jpg"; }); } public save() { this.database.createDocument(this.profile); this.location.back(); } } |
공정하게 말하자면, 저는 load 메서드에 내비게이션 스택에 역방향 탐색을 위한 각도 위치 서비스를 포함시켰습니다. 경로를 제외한 모든 것이 동일해야 합니다.
제 애플리케이션에는 인터넷에서 찾은 고양이 아바타 이미지가 있습니다.

나만의 아바타 이미지를 찾아서 적절하게 사용해야 합니다. 아바타 이미지 ~/ 는 이미지가 프로젝트의 앱 디렉터리로 이동합니다.
이제 화면에 데이터를 나열하기 위해 아직 생성되지 않은 페이지를 살펴볼 필요가 있습니다.
프로필 쿼리 및 UI의 목록에 프로필 추가하기
이론적으로 새 페이지는 지금까지의 모든 작업과 이전 가이드보다 더 간단해야 합니다. 프로젝트의 앱/컴포넌트/프로필 목록/프로필 목록.ts 파일을 열고 다음을 포함하세요:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import { Component, OnInit } from "@angular/core"; import { Location } from "@angular/common"; import { Router } from "@angular/router"; import { Couchbase } from "nativescript-couchbase"; @Component({ selector: "profile-list", templateUrl: "./components/profile-list/profile-list.html", }) export class ProfileListComponent implements OnInit { public profiles: Array; private database: any; public constructor(private router: Router, private location: Location) { } public ngOnInit() { } public refresh() { } public create() { } } |
위에는 프로필 목록 구성 요소 클래스에 모든 UI 바인딩 데이터를 저장하는 공용 변수와 Couchbase 데이터베이스에 대한 비공개 인스턴스를 생성합니다.
탐색 스택에서 앞으로 탐색하고 스택에서 뒤로 탐색을 감지할 수 있어야 하므로 스택에 라우터 그리고 위치 서비스를 생성자 메서드를 사용합니다. The 생성자 메서드도 다음을 수행합니다:
|
1 2 3 4 5 6 7 |
public constructor(private router: Router, private location: Location) { this.database = new Couchbase("data"); this.database.createView("profiles", "1", function(document, emitter) { emitter.emit(document._id, document); }); this.profiles = []; } |
위의 예에서 생성자 메서드를 사용하여 데이터베이스를 열고 새 MapReduce 뷰를 만듭니다. 이 뷰는 데이터베이스에 있는 모든 문서의 키-값 쌍을 반환한다는 점에서 매우 단순합니다. 이 시나리오에서는 반환되는 내용에 대한 조건부 논리가 없습니다. 하지만 프로필 맵리듀스 보기는 쿼리의 기초입니다.
해당 뷰를 쿼리하려면 새로 고침 메서드를 사용합니다:
|
1 2 3 4 5 6 7 |
public refresh() { this.profiles = []; let rows = this.database.executeQuery("profiles"); for(let i = 0; i < rows.length; i++) { this.profiles.push(rows[i]); } } |
쿼리 후 각 결과를 공개에 푸시합니다. 프로필 변수를 사용할 수 있습니다. 혼동하지 마세요. 프로필 변수는 프로필 보기.
|
1 2 3 4 5 6 |
public ngOnInit() { this.location.subscribe(() => { this.refresh(); }); this.refresh(); } |
그리고 ngOnInit 이후 트리거되는 생성자 메서드를 호출합니다. 쿼리를 실행할 뿐만 아니라 페이지로 돌아올 때 쿼리를 실행할 수 있도록 탐색 이벤트를 구독해야 합니다. 이는 생성자 및 ngOnInit 메서드는 로드 시에만 트리거되며 탐색 뒤로 이벤트는 트리거되지 않습니다.
마지막 방법은 create 메서드를 사용합니다:
|
1 2 3 |
public create() { this.router.navigate(["profile"]); } |
결국 버튼을 누르면 트리거되며 두 번째 화면으로 이동합니다.
이 페이지의 UI는 앱/컴포넌트/프로필 목록/프로필 목록.html는 다음과 같이 표시됩니다:
|
1 2 3 |
<label class="label"></label> |
그리고 는 공개 배열의 각 항목을 반복하여 행으로 변환합니다. 각 행은 두 개의 열로 구성되며, 첫 번째 이미지 열의 너비는 50이고 두 번째 열은 그에 맞게 늘어납니다.
결론
방금 키-값을 가져오는 방법을 보셨습니다. 네이티브 스크립트 문서 속성을 기반으로 데이터를 쿼리하기 위한 MapReduce 보기 쿼리를 추가하여 Couchbase 애플리케이션을 한 단계 더 발전시켰습니다. 프로필 데이터는 별다른 기능을 하지 않지만, 저장된 내용을 동기화하려면 어떻게 해야 할까요? 카우치베이스 를 다른 디바이스로 전송할 수 있나요? 이 부분은 다음 기회에 살펴보겠습니다.