콘텐츠로 이동

NativeScript 열 시트

NativeScript - JavaScript를 사용한 네이티브 모바일 앱

NativeScript는 JavaScript, TypeScript, Angular, Vue.js 또는 React를 사용하여 진정한 네이티브 모바일 애플리케이션 구축을 위한 오픈 소스 프레임워크입니다. WebViews 없이 Native API 및 UI 컴포넌트에 직접 액세스할 수 있습니다.

본문 바로가기

설치하기

자주 묻는 질문

카지노사이트

NativeScript 클립 설치하기

카지노사이트

개발 환경 설정

카지노사이트

시작하기

새 프로젝트 만들기

카지노사이트

프로젝트 템플릿

카지노사이트

프로젝트 구조

기본 구조

카지노사이트

app.js (엔트리 포인트)

카지노사이트

메인 페이지.xml (UI Markup)

카지노사이트

main-page.js (페이지 로그)

카지노사이트

제품정보 이름 *

프로젝트 관리

카지노사이트

개발 명령

ο 회원 관리

명령을 빌드

카지노사이트

플러그인 관리

카지노사이트

핵심 개념

관찰 및 데이터 바인딩

카지노사이트

관련 기사

카지노사이트

신청 Lifecycle

카지노사이트

UI 구성

기본 부품

카지노사이트

회사연혁

카지노사이트

고급 부품

카지노사이트

관련 기사

스택Layout

오프화이트

다운로드

카지노사이트

Flexbox로

오프화이트

비밀번호

카지노사이트

카테고리

카지노사이트

제품 소개

카지노사이트

- 연혁

제품 정보

카지노사이트

카지노사이트

탭 탐색

카지노사이트

회사 소개

<!-- RadSideDrawer (requires plugin) -->
<nsDrawer:RadSideDrawer xmlns:nsDrawer="@nativescript/ui-sidedrawer">
    <nsDrawer:RadSideDrawer.drawerContent>
        <StackLayout class="drawer-content">
            <Label text="Menu" class="drawer-header" />
            <Button text="Home" tap="{{ navigateToHome }}" />
            <Button text="Settings" tap="{{ navigateToSettings }}" />
            <Button text="About" tap="{{ navigateToAbout }}" />
        </StackLayout>
    </nsDrawer:RadSideDrawer.drawerContent>

    <nsDrawer:RadSideDrawer.mainContent>
        <Frame defaultPage="main-page" />
    </nsDrawer:RadSideDrawer.mainContent>
</nsDrawer:RadSideDrawer>
```의 경우

## 데이터 바인딩

### 원웨이 바인딩
```xml
<!-- Text binding -->
<Label text="{{ message }}" />
<Label text="{{ 'Hello ' + name }}" />

<!-- Property binding -->
<Button isEnabled="{{ canSubmit }}" />
<Image src="{{ imageUrl }}" />
<ActivityIndicator busy="{{ isLoading }}" />

<!-- Conditional binding -->
<Label text="{{ isLoggedIn ? 'Welcome' : 'Please login' }}" />
<Button visibility="{{ hasData ? 'visible' : 'collapsed' }}" />
```에 대하여

### 2 웨이 바인딩
```xml
<!-- TextField two-way binding -->
<TextField text="{{ username, mode=twoWay }}" />
<Slider value="{{ volume, mode=twoWay }}" />
<Switch checked="{{ isEnabled, mode=twoWay }}" />
<DatePicker date="{{ selectedDate, mode=twoWay }}" />
```의 경우

### 이벤트 바인딩
```xml
<!-- Event handlers -->
<Button text="Click Me" tap="{{ onButtonTap }}" />
<TextField text="{{ username }}" textChange="{{ onTextChange }}" />
<ListView items="{{ items }}" itemTap="{{ onItemTap }}" />
<SearchBar text="{{ query }}" submit="{{ onSearch }}" clear="{{ onClear }}" />
```에 대하여

### 목록 바인딩
```javascript
// View model with observable array
import { Observable, ObservableArray } from '@nativescript/core';

export function createViewModel() {
    const viewModel = new Observable();

    const items = new ObservableArray([
        { id: 1, name: 'Item 1', description: 'First item' },
        { id: 2, name: 'Item 2', description: 'Second item' },
        { id: 3, name: 'Item 3', description: 'Third item' }
    ]);

    viewModel.set('items', items);

    viewModel.set('addItem', function() {
        const newItem = {
            id: items.length + 1,
            name: `Item ${items.length + 1}`,
            description: `Item number ${items.length + 1}`
        };
        items.push(newItem);
    });

    viewModel.set('removeItem', function(index) {
        items.splice(index, 1);
    });

    viewModel.set('onItemTap', function(args) {
        const item = items.getItem(args.index);
        console.log('Tapped item:', item.name);
    });

    return viewModel;
}
```의 경우

카지노사이트

## 사이트맵

### 사이트맵 사이트맵
카지노사이트

### 사이트맵 지원하다
카지노사이트

카지노사이트

### 플랫폼-Specific 스타일링
카지노사이트

### 동적 스타일링
카지노사이트

## 플랫폼 API

### 회사소개
```javascript
import { Device, Screen, isAndroid, isIOS } from '@nativescript/core';

// Device information
console.log('Device Type:', Device.deviceType);
console.log('OS:', Device.os);
console.log('OS Version:', Device.osVersion);
console.log('Model:', Device.model);
console.log('Manufacturer:', Device.manufacturer);
console.log('UUID:', Device.uuid);
console.log('Language:', Device.language);
console.log('Region:', Device.region);

// Screen information
console.log('Screen Width:', Screen.mainScreen.widthDIPs);
console.log('Screen Height:', Screen.mainScreen.heightDIPs);
console.log('Screen Scale:', Screen.mainScreen.scale);

// Platform detection
if (isAndroid) {
    console.log('Running on Android');
    // Android-specific code
} else if (isIOS) {
    console.log('Running on iOS');
    // iOS-specific code
}

// Platform-specific API access
if (isAndroid) {
    const context = Application.android.context;
    const packageManager = context.getPackageManager();
    // Use Android APIs
} else if (isIOS) {
    const currentDevice = UIDevice.currentDevice;
    // Use iOS APIs
}
```의 경우

### 파일 시스템
```javascript
import { File, Folder, knownFolders, path } from '@nativescript/core';

// Known folders
const documentsFolder = knownFolders.documents();
const tempFolder = knownFolders.temp();
const appFolder = knownFolders.currentApp();

// Create file
const file = documentsFolder.getFile('data.txt');

// Write to file
file.writeText('Hello, NativeScript!')
    .then(() => {
        console.log('File written successfully');
    })
    .catch((error) => {
        console.error('Error writing file:', error);
    });

// Read from file
file.readText()
    .then((content) => {
        console.log('File content:', content);
    })
    .catch((error) => {
        console.error('Error reading file:', error);
    });

// Create folder
const folder = documentsFolder.getFolder('myFolder');

// List folder contents
folder.getEntities()
    .then((entities) => {
        entities.forEach((entity) => {
            console.log('Entity:', entity.name, entity.path);
        });
    });

// File operations
const sourceFile = documentsFolder.getFile('source.txt');
const targetFile = documentsFolder.getFile('target.txt');

// Copy file
sourceFile.copy(targetFile.path)
    .then(() => {
        console.log('File copied');
    });

// Move file
sourceFile.move(targetFile.path)
    .then(() => {
        console.log('File moved');
    });

// Delete file
file.remove()
    .then(() => {
        console.log('File deleted');
    });

// Check if file exists
if (file.exists) {
    console.log('File exists');
}

// Get file info
console.log('File size:', file.size);
console.log('Last modified:', file.lastModified);
```의 경우

### HTTP 요청
카지노사이트

### 지역 저장
```javascript
import { ApplicationSettings } from '@nativescript/core';

// Store data
ApplicationSettings.setString('username', 'john_doe');
ApplicationSettings.setNumber('userId', 123);
ApplicationSettings.setBoolean('isLoggedIn', true);

// Retrieve data
const username = ApplicationSettings.getString('username', 'default_user');
const userId = ApplicationSettings.getNumber('userId', 0);
const isLoggedIn = ApplicationSettings.getBoolean('isLoggedIn', false);

// Remove data
ApplicationSettings.remove('username');

// Check if key exists
if (ApplicationSettings.hasKey('username')) {
    console.log('Username exists');
}

// Clear all data
ApplicationSettings.clear();

// Store complex objects
const user = {
    id: 123,
    name: 'John Doe',
    email: 'john@example.com'
};

ApplicationSettings.setString('user', JSON.stringify(user));

// Retrieve complex objects
const storedUser = JSON.parse(ApplicationSettings.getString('user', '{}'));
```의 경우

## 플러그인

### 핵심 플러그인
```bash
# Camera plugin
ns plugin add @nativescript/camera

# Geolocation plugin
ns plugin add @nativescript/geolocation

# Local notifications
ns plugin add @nativescript/local-notifications

# Social share
ns plugin add @nativescript/social-share

# Email plugin
ns plugin add @nativescript/email

# Phone plugin
ns plugin add @nativescript/phone

# Fingerprint authentication
ns plugin add @nativescript/fingerprint-auth

# Secure storage
ns plugin add @nativescript/secure-storage

# Background HTTP
ns plugin add @nativescript/background-http
```를 호출합니다.

### Camera Plugin 사용
```javascript
import { Camera, requestPermissions } from '@nativescript/camera';

export function takePicture() {
    requestPermissions()
        .then(() => {
            const options = {
                width: 300,
                height: 300,
                keepAspectRatio: true,
                saveToGallery: false
            };

            return Camera.takePicture(options);
        })
        .then((imageAsset) => {
            console.log('Picture taken:', imageAsset);
            // Use the image
            const image = new Image();
            image.src = imageAsset;
        })
        .catch((error) => {
            console.error('Camera error:', error);
        });
}

export function selectFromGallery() {
    const options = {
        width: 300,
        height: 300,
        keepAspectRatio: true
    };

    Camera.requestPermissions()
        .then(() => {
            return Camera.selectFromGallery(options);
        })
        .then((imageAsset) => {
            console.log('Image selected:', imageAsset);
        })
        .catch((error) => {
            console.error('Gallery error:', error);
        });
}
```의 경우

### Geolocation 플러그인 사용
```javascript
import { Geolocation, CoreTypes } from '@nativescript/geolocation';

export function getCurrentLocation() {
    const options = {
        desiredAccuracy: CoreTypes.Accuracy.high,
        maximumAge: 5000,
        timeout: 10000
    };

    Geolocation.getCurrentLocation(options)
        .then((location) => {
            console.log('Location:', location);
            console.log('Latitude:', location.latitude);
            console.log('Longitude:', location.longitude);
            console.log('Altitude:', location.altitude);
            console.log('Speed:', location.speed);
        })
        .catch((error) => {
            console.error('Location error:', error);
        });
}

export function watchLocation() {
    const options = {
        desiredAccuracy: CoreTypes.Accuracy.high,
        updateDistance: 10,
        minimumUpdateTime: 1000
    };

    const watchId = Geolocation.watchLocation(
        (location) => {
            console.log('Location update:', location);
        },
        (error) => {
            console.error('Location error:', error);
        },
        options
    );

    // Stop watching
    setTimeout(() => {
        Geolocation.clearWatch(watchId);
    }, 30000);
}
```로

### 사용자 정의 플러그인 개발
카지노사이트

## Angular 통합

### 설정 Angular 프로젝트
오프화이트

###  모듈
카지노사이트

### 로그아웃
__CODE_BLOCK_49_로그

### 회사연혁
카지노사이트

```html
<!-- home.component.html -->
<ActionBar title="Home" class="action-bar">
    <ActionItem text="Refresh" (tap)="onRefresh()" ios.position="right"></ActionItem>
</ActionBar>

<GridLayout rows="*">
    <ActivityIndicator [busy]="isLoading" *ngIf="isLoading"></ActivityIndicator>

    <ListView [items]="items" (itemTap)="onItemTap($event.object.bindingContext)" *ngIf="!isLoading">
        <ng-template let-item="item">
            <GridLayout columns="auto, *" rows="auto, auto" class="list-item">
                <Label [text]="item.title" row="0" col="1" class="item-title"></Label>
                <Label [text]="item.description" row="1" col="1" class="item-description"></Label>
            </GridLayout>
        </ng-template>
    </ListView>
</GridLayout>
```를 호출합니다.

### 제품정보
```typescript
// data.service.ts
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { Http } from '@nativescript/core';

@Injectable({
    providedIn: 'root'
})
export class DataService {
    private apiUrl = 'https://api.example.com';

    constructor() { }

    getItems(): Observable<any[]> {
        return new Observable((observer) => {
            Http.getJSON(`${this.apiUrl}/items`)
                .then((data: any[]) => {
                    observer.next(data);
                    observer.complete();
                })
                .catch((error) => {
                    observer.error(error);
                });
        });
    }

    getItem(id: number): Observable<any> {
        return new Observable((observer) => {
            Http.getJSON(`${this.apiUrl}/items/${id}`)
                .then((data: any) => {
                    observer.next(data);
                    observer.complete();
                })
                .catch((error) => {
                    observer.error(error);
                });
        });
    }

    createItem(item: any): Observable<any> {
        return new Observable((observer) => {
            Http.request({
                url: `${this.apiUrl}/items`,
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                content: JSON.stringify(item)
            })
            .then((response) => {
                observer.next(response.content.toJSON());
                observer.complete();
            })
            .catch((error) => {
                observer.error(error);
            });
        });
    }
}
```의 경우

## Vue.js 통합

### 설정 Vue 프로젝트
카지노사이트

### 주요 카지노사이트

### Vue 성분
```vue
<!-- components/Home.vue -->
<template>
    <Frame>
        <Page>
            <ActionBar title="Home" />

            <GridLayout rows="auto, *">
                <StackLayout row="0" class="form">
                    <TextField v-model="newItem" hint="Enter new item" />
                    <Button text="Add Item" @tap="addItem" class="btn btn-primary" />
                </StackLayout>

                <ListView row="1" :items="items" @itemTap="onItemTap">
                    <template #default="{ item, index }">
                        <GridLayout columns="*, auto" class="list-item">
                            <Label col="0" :text="item.name" class="item-name" />
                            <Button col="1" text="Delete" @tap="deleteItem(index)" class="btn btn-secondary" />
                        </GridLayout>
                    </template>
                </ListView>
            </GridLayout>
        </Page>
    </Frame>
</template>

<script>
import { ref, reactive } from 'vue';

export default {
    setup() {
        const newItem = ref('');
        const items = reactive([
            { id: 1, name: 'Item 1' },
            { id: 2, name: 'Item 2' },
            { id: 3, name: 'Item 3' }
        ]);

        const addItem = () => {
            if (newItem.value.trim()) {
                items.push({
                    id: Date.now(),
                    name: newItem.value
                });
                newItem.value = '';
            }
        };

        const deleteItem = (index) => {
            items.splice(index, 1);
        };

        const onItemTap = (event) => {
            const item = event.item;
            console.log('Tapped item:', item.name);
        };

        return {
            newItem,
            items,
            addItem,
            deleteItem,
            onItemTap
        };
    }
};
</script>

<style scoped>
.form {
    padding: 20;
}

.list-item {
    padding: 16;
    border-bottom-width: 1;
    border-bottom-color: #e0e0e0;
}

.item-name {
    font-size: 16;
    vertical-align: center;
}

.btn {
    margin: 8;
}
</style>
```로

### Vue 대패
카지노사이트

## React 통합

### React 프로젝트 설정
카지노사이트

###  구성
카지노사이트

### React 구성 요소
```jsx
// components/Home.jsx
import React, { useState, useEffect } from 'react';

export function Home({ navigation }) {
    const [items, setItems] = useState([]);
    const [newItem, setNewItem] = useState('');
    const [isLoading, setIsLoading] = useState(false);

    useEffect(() => {
        loadData();
    }, []);

    const loadData = async () => {
        setIsLoading(true);
        try {
            // Simulate API call
            const data = [
                { id: 1, name: 'Item 1', description: 'First item' },
                { id: 2, name: 'Item 2', description: 'Second item' },
                { id: 3, name: 'Item 3', description: 'Third item' }
            ];
            setItems(data);
        } catch (error) {
            console.error('Error loading data:', error);
        } finally {
            setIsLoading(false);
        }
    };

    const addItem = () => {
        if (newItem.trim()) {
            const item = {
                id: Date.now(),
                name: newItem,
                description: `Description for ${newItem}`
            };
            setItems([...items, item]);
            setNewItem('');
        }
    };

    const deleteItem = (id) => {
        setItems(items.filter(item => item.id !== id));
    };

    const navigateToDetails = (item) => {
        navigation.navigate('Details', { item });
    };

    return (
        <page>
            <actionBar title="Home" />

            <gridLayout rows="auto, *">
                <stackLayout row={0} className="form">
                    <textField
                        text={newItem}
                        onTextChange={(args) => setNewItem(args.value)}
                        hint="Enter new item"
                    />
                    <button
                        text="Add Item"
                        onTap={addItem}
                        className="btn btn-primary"
                    />
                </stackLayout>

                {isLoading ? (
                    <activityIndicator row={1} busy={true} />
                ) : (
                    <listView
                        row={1}
                        items={items}
                        onItemTap={(args) => navigateToDetails(args.item)}
                        cellFactory={(item) => (
                            <gridLayout columns="*, auto" className="list-item">
                                <stackLayout col={0}>
                                    <label text={item.name} className="item-name" />
                                    <label text={item.description} className="item-description" />
                                </stackLayout>
                                <button
                                    col={1}
                                    text="Delete"
                                    onTap={() => deleteItem(item.id)}
                                    className="btn btn-secondary"
                                />
                            </gridLayout>
                        )}
                    />
                )}
            </gridLayout>
        </page>
    );
}
```에

### React ```jsx
// hooks/useApi.js
import { useState, useEffect } from 'react';
import { Http } from '@nativescript/core';

export function useApi(url) {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        const fetchData = async () => {
            try {
                setLoading(true);
                const result = await Http.getJSON(url);
                setData(result);
            } catch (err) {
                setError(err);
            } finally {
                setLoading(false);
            }
        };

        fetchData();
    }, [url]);

    return { data, loading, error };
}

// Usage in component
export function DataComponent() {
    const { data, loading, error } = useApi('https://api.example.com/data');

    if (loading) return <activityIndicator busy={true} />;
    if (error) return <label text={`Error: ${error.message}`} />;

    return (
        <listView
            items={data}
            cellFactory={(item) => (
                <label text={item.name} />
            )}
        />
    );
}
```의 경우

## 제품정보

### 단위 시험
카지노사이트

### 시험 구성
카지노사이트

### Unit Test 예제
```javascript
// tests/example.spec.js
describe('Calculator', function() {
    let calculator;

    beforeEach(function() {
        calculator = new Calculator();
    });

    it('should add two numbers correctly', function() {
        const result = calculator.add(2, 3);
        expect(result).toBe(5);
    });

    it('should subtract two numbers correctly', function() {
        const result = calculator.subtract(5, 3);
        expect(result).toBe(2);
    });

    it('should multiply two numbers correctly', function() {
        const result = calculator.multiply(4, 3);
        expect(result).toBe(12);
    });

    it('should divide two numbers correctly', function() {
        const result = calculator.divide(10, 2);
        expect(result).toBe(5);
    });

    it('should throw error when dividing by zero', function() {
        expect(function() {
            calculator.divide(10, 0);
        }).toThrow();
    });
});

// Calculator class
class Calculator {
    add(a, b) {
        return a + b;
    }

    subtract(a, b) {
        return a - b;
    }

    multiply(a, b) {
        return a * b;
    }

    divide(a, b) {
        if (b === 0) {
            throw new Error('Division by zero');
        }
        return a / b;
    }
}
```의 경우

### 사이트맵 제품정보
카지노사이트

카지노사이트

## - 연혁

### 메모리 관리
카지노사이트

### 이미지 최적화
카지노사이트

### 공지사항
카지노사이트

## 계정 만들기

### Android 배포
카지노사이트

### iOS 배포
```bash
# Build for device
ns build ios --for-device --release

# Build with provisioning profile
ns build ios --for-device --release --provision "MyApp Distribution Profile"

# Create IPA
ns build ios --for-device --release --provision "MyApp Distribution Profile" --team-id TEAM_ID

# Upload to App Store
# Use Xcode or Application Loader to upload the IPA
```의 경우

### 연속 통합
카지노사이트

## 최고의 연습

### 프로젝트 구조
app/ ├── core/ # Core functionality │ ├── services/ # Business logic services │ ├── models/ # Data models │ ├── utils/ # Utility functions │ └── constants/ # App constants ├── shared/ # Shared components │ ├── components/ # Reusable UI components │ ├── directives/ # Custom directives │ └── pipes/ # Custom pipes ├── features/ # Feature modules │ ├── home/ # Home feature │ ├── profile/ # Profile feature │ └── settings/ # Settings feature ├── assets/ # Static assets │ ├── images/ │ ├── fonts/ │ └── sounds/ └── styles/ # Global styles ├── _variables.scss ├── _mixins.scss └── app.scss ```의 경우

회사연혁

카지노사이트

성과 모범 사례

```javascript // Optimize data binding // Use one-time binding for static data // XML: text="{{ message, mode=oneTime }}"

// Minimize property changes class OptimizedViewModel extends Observable { constructor() { super(); this._batchUpdates = false; this._pendingUpdates = {}; }

startBatch() {
    this._batchUpdates = true;
}

endBatch() {
    this._batchUpdates = false;
    Object.keys(this._pendingUpdates).forEach(key => {
        super.set(key, this._pendingUpdates[key]);
    });
    this._pendingUpdates = {};
}

set(name, value) {
    if (this._batchUpdates) {
        this._pendingUpdates[name] = value;
    } else {
        super.set(name, value);
    }
}

}

// Use efficient list operations // Bad items.forEach((item, index) => { if (item.shouldRemove) { items.splice(index, 1); } });

// Good const itemsToKeep = items.filter(item => !item.shouldRemove); items.splice(0, items.length, ...itemsToKeep);

// Optimize image loading const optimizeImageLoading = (imageView, url, placeholder) => { // Show placeholder immediately imageView.src = placeholder;

// Load actual image asynchronously
ImageSource.fromUrl(url)
    .then(imageSource => {
        imageView.imageSource = imageSource;
    })
    .catch(error => {
        console.error('Image loading failed:', error);
        // Keep placeholder or show error image
    });

};

// Use proper cleanup class ComponentManager { constructor() { this.components = new Map(); this.timers = new Set(); this.subscriptions = new Set(); }

addTimer(timer) {
    this.timers.add(timer);
}

addSubscription(subscription) {
    this.subscriptions.add(subscription);
}

cleanup() {
    // Clear timers
    this.timers.forEach(timer => clearTimeout(timer));
    this.timers.clear();

    // Unsubscribe from observables
    this.subscriptions.forEach(sub => {
        if (sub && sub.unsubscribe) {
            sub.unsubscribe();
        }
    });
    this.subscriptions.clear();

    // Clear component references
    this.components.clear();
}

} ```로


제품정보

NativeScript는 웹 기술을 사용하여 진정한 네이티브 모바일 응용 프로그램을 구축하기위한 강력한 플랫폼을 제공합니다.

** 키 장점 : ** - True Native Performance: WebViews 없이 기본 API에 직접 액세스 - ** 코드 공유 : 기본 UI를 유지하면서 플랫폼 전반에 걸쳐 비즈니스 논리 공유 - **Framework Flexibility: Angular, Vue.js, React, vanilla JavaScript 지원 - Native UI: 플랫폼 별 네이티브 UI 구성 요소 - ** 플러그인 **: 기본 기능에 대한 플러그인의 풍부한 생태계

** 최고의 사용 사례:** - 기본 성능과 UI를 요구하는 앱 - Cross-platform 앱과 복잡한 비즈니스 로직 - 웹 개발 전문 팀 - 광대한 Native API 액세스를 필요로 하는 앱 - 사용자 정의 요구 사항이있는 기업 응용

조건: - Hybrid Framework보다 Steeper 학습 곡선 - 웹 기반 솔루션에 비해 더 큰 앱 크기 - 플랫폼별 테스트 - 기본 플랫폼 개념을 이해해야

NativeScript는 뛰어난 성능과 플랫폼 통합으로 웹 기술을 활용하고 싶은 개발자들에게 이상적입니다.

<문서> 기능 copyToClipboard () 이름 * const 명령어 = document.querySelectorAll('code'); let allCommands = ''; 명령. forEach(cmd =>의 경우 모든Commands +=cmd.textContent + navigator.clipboard.write텍스(allCommands); alert('모든 명령은 클립보드에 복사!'); 이름 *

함수 생성PDF() { 창. 인쇄 (); 이름 *