webstorm 에서 자동완성 쌍따옴표를 따옴표로

웹스톰을 기본설치하고 angular 플러그인을 설치하고 난 뒤에 import {} 를 하고 나면 자동완성으로 쌍또옴표를 사용한다

이거 찾는다고 10분을 허비함.

이를 해결하기 위해서는 설정헤서 다음부분을 수정하면 된다.

Imgur

반응형

라즈베리파이3 b+ 을 사용하고 있는데, 현재는 zero w 를 구입해서 세팅을 하다가 일정 중요한 부분을 기록하다.

라즈베리파이 기초설정

SSH 모드를 사용해서 설정하는게 편합니다. 더 편하게 하려면 GUI 모드를 이용해서 접속을 하시면 더 편합니다.

WIFI 잡기

주위에 잡을 수 있는 와이파이 정보를 읽어옵니다.

# sudo iwlist wlan0 scan

Imgur

ESSID 명이 접속을 네트워크 암호를 나타냅니다.

다음명령어를 통해서 테스트를 해 봅니다.

# wpa_passphrase SSID이름 비밀번호

여러가지 문구나 나오는게 있는데, 이부분은 보안을 위해서 설정할 수 있는 부분이기도 한데, 추가 정보는 이쪽을 통해서 보세요. 처음 사용자에게 중요한 부분은 아닙니다.

설정 파일을 편집 합니다.

# sudo vi /etc/wpa_supplicant/wpa_supplicant/conf
country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="네트워크이름"
    psk="암호"
}

이렇게 입력을 해 준 후에 리부팅을 해 줍니다.

# sudo shurdown -r now

멀티 와이파이 잡기

여러장소에서 와이파이를 잡기위해서 멀티 와이파이를 설정 할 수 있습니다.

terminal 을 통해서 실행

새로운 걸 설치 안하고, 위의 방법을 통해서 같은 방법으로 문구만 추가해 주면 됩니다.

country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="네트워크이름"
    psk="암호"
}

# 아래 추가 된 문구
network={
    ssid="네트워크이름2"
    psk="암호2"
}

콘솔 어플을 통해서 사용하는 방법

아래의 명령어로 설치를 진행 한 후 실행하기( 설치용량 4mb )

# sudo apt-get install wicd-curses -y
# sudo wicd-curses

실행하면 나오는 화면

Imgur

지금은 잡히는 와이파이가 하나 밖에 없습니다.

여기서 키보드 오른쪽방향키를 누르면 설정 모드로 들어갈 수 있습니다. 여기서 KeyAutomatically connect to this network 를 눌러서 추가합니다.

Imgur

세팅값은 /etc/wicd/wireless-settings.conf 에 저장.

블루투스 잡기

블루투스 모드 컨트롤에 들어갑니다.

# sudo bluetoothctl
agent on
default-agent
discoverable on
scan on

리스트들이 보이면 자신이 원하는 블루투스 기기을 선택해서 붙여넣기 합니다.

pair xx:xx:xx:xx:xx:xx

여러가지 요구 미션이 잇는데 수행하면 pair 가 완료 됩니다.

메모리에 올려줍니다.

trust xx:xx:xx:xx:xx:xx

Imgur

여기까지 하고 리붓을 해도 잘 잡힙니다.
만약 리붓을 해도 안 잡히면 다음문서를 참조하세요

참조문서

반응형

centos 7 커널 최신버전으로 설치하기

참조

커널 version 확인 하기

# uname -sr

CentOS 7.3 최신버전을 설치했는데도 저의 커널은 3.1 버전이었습니다.

업데이트 진행

ELRepo repository 를 CentOS7 에 추가합니다.

# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm

설치가능 커널목록 을 확인 합니다.

# yum --disablerepo="*" --enablerepo="elrepo-kernel" list available

커널을 설치합니다.

# yum --enablerepo=elrepo-kernel install kernel-ml

여기가지 설치가 끝났습니다.
이제 부팅 순서를 변경해야 새로운 커널로 부팅이 되는 것을 확인 할 수 있습니다.

현재 부팅 순서 변경하기

ssh 로 접속해서 하려니 속이 터졌습니다.

/etc/default/grub파일의 GRUB_DEFAULT=0 으로 추가를 해 줘도 새로운 커널로 부팅이 안되서 찾와봤는데, 아래처럼 하는게 제일 확실한 방법 인 것을 알게 되었습니다.

오타가 나는 순간 부팅이 안되고 물리적으로 서버를 찾아가야 하는 합니다.

현재 부팅 순서 확인하기

# grub2-editenv list
saved_entry=Fedora (3.14.9-200.fc20.x86_64) 20 (Heisenbug)

시스템에 등록 된 부팅커널 확인

# grep ^menuentry /boot/grub2/grub.cfg | cut -d "'" -f2
CentOS Linux (4.13.2-1.el7.elrepo.x86_64) 7 (Core)
CentOS Linux (3.10.0-693.2.2.el7.x86_64) 7 (Core)
CentOS Linux (3.10.0-514.26.2.el7.x86_64) 7 (Core)
CentOS Linux (0-rescue-99469085913545568c1e75ad9d37bd09) 7 (Core)

uefi로 설치하신 분은 /boot/efi/EFI/centos/grub.cfg 에 위치하고 있습니다.
# grep ^menuentry /boot/efi/EFI/centos/grub.cfg | cut -d “’” -f2

부팅커널 변경하기

위의 리스트에서 붙여넣기 해 주세요. 괜히 직접 쓰다가 오타나지 마세요.

# grub2-set-default "CentOS Linux (4.13.2-1.el7.elrepo.x86_64) 7 (Core)"

부팅 설정이 변경 됐는지 확인 해 봅니다.

# grub2-editenv list
saved_entry=CentOS Linux (4.13.2-1.el7.elrepo.x86_64) 7 (Core)

재부팅 및 확인

다음 명령어를 통해서 재부팅을 합니다.

# reboot

변경 된 것을 확인 할 수 있습니다.

[root@ML350 ~]# uname -sr
Linux 4.13.2-1.el7.elrepo.x86_64
반응형

'개발 > 리눅스' 카테고리의 다른 글

nginx + php71 + php-fpm 설치하기  (0) 2018.06.20
centos 7 yum 깨짐  (0) 2017.12.05
리눅스 daemon 항목들 정리  (0) 2016.08.09
소유자, 그룹 변경하기  (0) 2016.07.28
우분투에서 일본어 사용하기  (0) 2016.07.18

golang 1.9

golang 1.9 release news

소개

최신 Go 버전 1.9 버전은 Go 1.8 이후 6 개월 후에 출시되고, Go 1.x 시리즈에서 10 번째 릴리스입니다. 언어에는 두 가지 변경 사항이 있습니다.
type alias에 대한 지원 추가 및 구현이 부동 소수점 연산을 통합 할 수 있는 시점 정의하는 부분입니다. 대부분의 변경 사항은 toolchain, runtime 및 라이브러리의 구현에 있습니다. 언제나 그렇듯이 이 릴리스는 Go 1 호환성을 유지합니다. 거의 모든 Go 프로그램이 이전처럼 계속해서 컴파일되고 실행될 것입니다.

이 릴리스에서는 명쾌한 단조로운 시간 지원 기능을 추가하고, 패키지 내의 기능 컴파일을 병렬화하며 test helper 기능을 보다 잘 지원하고 새로운 비트 조작 패키지를 포함하며, 새로운 동시 map type을 제공합니다.

오늘 brew update를 했더니 golang이 업그레이드가 된 사실을 알게 되었습니다. 그래서 중요한 변경부분을 적어 봅니다.

언어의 변경점

두가지 변경점이 있습니다.

Go는 패키지간에 유형을 이동하면서 점진적인 코드 복구를 지원하는 type alias을 지원합니다. type 디자인 문서리팩토링에 대한 기사에서 문제를 자세히 설명합니다. 즉, type alias 선언은 다음과 같은 형식을 취합니다.

type T1 = T2

이 선언은 T2로 표시된 type에 대한 대체 철자 인 alias T1을 도입합니다. 즉, T1과 T2는 모두 같은 type을 나타냅니다.

언어의 작은 변경점은 아키텍처의 “fused multiply and add”(FMA) 명령어를 사용하여 중간 결과를 반올림하지 않고, x*y+z를 계산하는 것과 같이 부동 소수점 연산을 함께 구현할 수 있는 언어구현을 의미합니다 x * y. 강제적으로 중간의 반올림을 실시하려면, float64 (x * y) + z라고 기입합니다.

Ports

이 릴리스에는 지원되는 새로운 운영 체제 또는 프로세서 아키텍처가 없습니다.

ppc64x requires POWER8

FreeBSD

OpebBSD 6.0

known Issue

NetBSD 커널 충돌로 인해 1.9 개발동안 NetBSD 빌더 실행이 중단되었습니다 (NetBSD 7.1까지 포함). Go 1.9가 릴리스됨에 따라 NetBSD 7.1.1이 수정되었습니다. 그러나 현재로서는 테스트 통과 한 NetBSD 빌더가 없습니다. 다양한 NetBSD 문제를 조사하는 데 도움을 주시면 감사하겠습니다.

Tools

병렬 컴파일

Go 컴파일러는 이제 다중 코어를 활용하여 패키지의 함수를 병렬로 컴파일하는 기능을 지원합니다. 이것은 별도 패키지의 병렬 컴파일에 대한 go 명령의 기존 지원에 추가됩니다. 병렬 컴파일은 기본적으로 켜져 있지만 환경 변수를 아래와 같이 변경하면 비활성화 할 수 있습니다.

GO19CONCURRENTCOMPILATION = 0

Vendor matching with ./…

Moved GOROOT

Compiler Toolchain

어샘블러

Doc

긴 인수 목록들이 생략됩니다. 이 것은 go doc 의 가독성을 개량했습니다.
구조체 필드에 대한 문서보기가 지원됩니다. 예를 들어 doc http.Client.Jar로 이동하십시오.

type Client struct {
    // Jar specifies the cookie jar.
    //
    // The Jar is used to insert relevant cookies into every
    // outbound Request and is updated with the cookie values
    // of every inbound Response. The Jar is consulted for every
    // redirect that the Client follows.
    //
    // If Jar is nil, cookies are only sent if they are explicitly
    // set on the Request.
    Jar CookieJar

    // ... other fields elided ...

ENV

go env --json을 통해 json 형식으로 출력할 수 있습니다.

Test

Pprof

Vet

vet명령은 go tool에 더 잘 통합되어 있어서 vet는 모든 표준 빌드 플래그를 지원하고, vet 플래그는 이제 vet와 go tool vet에서 사용할 수 있습니다.

Gccgo

Runetime

inlined frames이 포함된 스택호출

성능

언제나 그렇듯이 변경 사항은 매우 일반적이며 다양하여 성능에 대한 정확한 설명을 하기 어렵습니다. 대부분의 프로그램은 가비지 컬렉터의 속도 향상, 향상된 코드 생성 및 코어 라이브러리의 최적화로 인해 조금 더 빠르게 실행될 것입니다.

가비지 콜렉터(Garbage Collector)

세계 표준 가비지 콜렉션을 트리거하는데 사용 된 라이브러리 함수는 이제 동시 가비지 콜렉션을 트리거합니다. 특히 runtime.GC, debug.SetGCPercent 및 debug.FreeOSMemory는 동시 가비지 콜렉션을 트리거하고, 가비지 콜렉션이 완료 될 때까지 호출 goroutine 만 차단합니다.

debug.SetGCPercent 함수는 새로운 GOGC 값으로 인해 즉시 필요한 경우에만 가비지 수집을 트리거합니다. 이렇게하면 GOGC를 즉석에서 조정할 수 있습니다.

큰 오브젝트 할당 성능은 대형 오브젝트가 많은 대형 (> 50GB) 힙을 사용하는 어플리케이션에서 상당히 향상됩니다.

매우 큰 힙에 대해서도 runtime.ReadMemStats 함수는 이제 100μs보다 적게 걸립니다.

코어 라이브러리

새로운 비트조작 패키지

Go 1.9에는 새로운 패키지 인 math/bits가 포함되어 있으며 비트 조작을위한 최적화 된 구현이 포함되어 있습니다. 대부분의 아키텍처에서이 패키지의 함수는 컴파일러에서 추가로 인식되며 추가 성능을 위해 내장 함수로 처리됩니다.

Test.Helper function

새로운 (T).Helper( B).Helper 메서드는 호출 함수를 테스트 도우미 함수로 표시합니다. 파일 및 줄 정보를 인쇄 할 때 해당 기능은 건너 뜁니다. 이렇게하면 사용자에게 유용한 줄 번호를 사용하면서 테스트 도우미 함수를 작성할 수 있습니다.

동시 발생하는 MAP

sync 패키지의 새로운 map 패키지는 amortized-constant-time, 저장 및 삭제가 포함 된 동시 map입니다. 여러 goroutine이 Map의 메소드를 동시에 호출하는 것이 안전합니다.

Profiler Labels

기타 소규모 변경점

문서가 너무 많다… ㅠㅠ

반응형

마무리

To Do 응용 프로그램을 실제 프로토 타입으로 확장해 보겠습니다. 우리는 처음 세장에서 필요한 모든 것을 만들어 작동하는 응용 프로그램을 만들었습니다. 우리는 서비스 태스크를 수정하여 추가 및 제거 메소드를 작성한 다음 Bootstrap 테마를 적용하여 이쁘게 만들어 고겠습니다.

/app폴더에 있는 tasks.service.ts 파일을 수정하면서 시작하겠습니다.

import {TASKS} from './sample.tasks';
import {Injectable} from 'angular2/core';

@Injectable()
export class TaskService {
  getTasks() {
    return TASKS;
  };
  addTask(task) {
    TASKS.push(task);
  };
  deleteTask (task) {
    for (var i=0; i<TASKS.length; i++) {
      if (TASKS[i].id === task.id) {
        TASKS.splice(i,1);
        break;
      }
    }    
  };
}

두가지 메소드를 추가 했습니다.

addTask는 task를 매개변수로 허용하고, deleteTask 또한 task를 매개변수로 허용하고 있습니다.
addTask메소드는 새로운 task를 배열에 추가하고, deleteTask는 전송 된 작업 개체의 ID 를 기반으로 배열에서 작업을 제거 합니다.

다음으로 수정할 파일은 index.html은 app폴더 바깥에 위치하고 있습니다.
Bootstrap CDN 을 통해서 Bootstrap CSS 를 추가할 것입니다.

index.html 를 수정합니다.

<html>
  <head>
    <title>Angular 2 - My Todo List</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>

    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <script>
      System.config({
        packages: {
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
  </head>

  <body>
    <my-component>Loading...</my-component>
  </body>
</html>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

Bootstrap CDN을 추가했습니다.

/app폴더에 위치하고 있는 app.component.ts파일을 수정합니다.

import {Component} from 'angular2/core';
import {HighlightDirective} from './highlight.directive';
import {TaskService} from './task.service';
import {Task} from './tasks';
import {OnInit} from 'angular2/core';

@Component({
  selector: 'my-component',
  templateUrl: 'app/app.component.html',
  directives: [HighlightDirective],
  providers: [TaskService]

})
export class MyComponent {
    public name: String;
    public today: Date;
    public task: String;
    public taskList: Task[];

constructor(private _taskService: TaskService) {
        this.name = 'Angular 2 Rocks !';
        this.today = new Date();       
        this.task = '';
        this.taskList = this._taskService.getTasks();

    }
    removeTask(item) {
         this._taskService.deleteTask(item);
    }
    addNewTask() {
        this._taskService.addTask ( { id: Math.floor((Math.random() * 10) + 10), name : this.task });
        this.task = '';
    }
}

sayMyName() 메소드를 제거하고 deleteTask, addNewTask 메소드를 추가했습니다. 이 앱은 데모앱이므로 따로 ID 등 확인은 없습니다.
프로덕션 환경에서는 이러한 방법을 보다 효과적으로 작동시키기 위해 더 많은 데이터 검증이 필요한 것입니다.

/app 폴더에 있는app.component.html파일을 수정 합니다.

<h1>{{today | date:"fullDate"}}</h1>
<div>
    <div class="form-group">
        <label for="usr">New Task:</label>
        <input [(ngModel)]="task"  class="form-control"> 
    </div>
    <button (click)="addNewTask()"  class='btn-default' myHighlight>Add Task</button>
</div>
<div>
    <div class="list-group">
        <a href="#" (click)="removeTask(item)" *ngFor="#item of taskList" class="list-group-item">{{item.name}}</a>
    </div>
</div>

우리는 목록을 제거하고, 추가 할 수 있는 버튼을 부트스트랩 테마와 함께 적용 했습니다.

마치며

반응형

의속성 주입(Dependency Injection)

의속성 주입(Dependency Injection)은 Angular에서 가장 강력한 기능 중에 하나 입니다.

Angular 1.x 에서의 의존주입은 몇가지 제한 사항이 있었습니다.

내부캐시(Internal cache) : 종손성은 싱글톤 입니다. 라이프 사이클당 한번만 생성
네임스페이스 출동(Namespace collision) : 오직 한가지 유형만을 가질 수 있습니다.
단단한 결합(Tightly coupled) : Angular 1.x 프레임워크에 내장되어 있습니다.

의존성 삽입을 설명하기 위해 다음 예제를 사용합니다.
차를 만드는 클래스를 생성하겠습니다.
일반적인 방법으로 아래와 같습니다.

class Car {
  constructor() {
    this.engine = new Engine();
    this.tyres = Tyres.getInstance();
  }
}

이 방법은 괜찮습니다. 하지만, 우리는 엔진 생성자와 싱글 톤 타이어에서 엔진을 얻을 수 있습니다.
만약 우리가 MockEngine 을 생성자로 대체해서 코드를 테스트해야 한다면 새로운 코드를 작성해야 합니다.
테스트 할 수 잇는 코드를 만들면 우연히 재사용 가능한 코드를 빌드하게 됩니다. 이 코드르 더 재사용 가능하게 만드는 한가지 방법은 TypeScript 생성자를 사용하여 형식과 값을 전달하는 것입니다.
다음은 그 예입니다.

class Car {
  constructor(engine, tires) {
    this.engine = engine;
    this.tyres = tyres;
  }
}

우리는 생성자로부터 의존성 생성을 제거하고 모든 필요한 종속성을 기대학 위해 생성자 함수를 확장했습니다. 이제 코드의 구현을 하드 코딩하지 않았습니다.
우리는 생성자에 옮겼습니다.
새차를 만드려면 다음과 같이 실행하면 됩니다.

var car = new Car(
  new Engine(),
  new Tyres()
);

코드를 테스트 할 필요가 있다면 모의 의존성을 보낼 수 있습니다. 예를 들면 다음과 같습니다.

var car = new Car(
  new MockEngine(),
  new MockTyres()
);

이제, 이것이 의존성 주입입니다.
Angular2 에서의 의존성 주입은 다음과 같이 구성이 됩니다.

인젝터(Injector) : API 를 노출하는 객체입니다.
공급자(Provider) : 인젝터에게 종속성의 인스턴스를 만드는 방법을 알려줍니다.
종속성(Dependency) : 객체를 생성해야 하는 유형

Angular2 에서는 동일한 객체를 만드려면 다음과 같이 정의합니다.

import { Injector } from 'angular2/core';

var injector = Injector.resolveAndCreate([
  Car,
  Engine,
  Tyres
]);

var car = injector.get(Car);

Angular2 에서 import하는 Injector는 Injector.resolveAndCreate()를 생성하는데 도움을 주는 API 를 확장하는 팩토리 함수이며 이는 제공자의 목록을 가져옵니다.

TypeScript 에서는 다음과 같이 Car 클래스를 정의합니다.

class Car {
  constructor(engine: Engine, tires: Tires, doors: Doors) {
    ...
  }
}

이 방법으로 의존성 주입을 생성함으로 이름 충돌 문제를 제거 할 수 있습니다.이 구조화 된 형식은 Angular 1.x 의 모든 문제를 제거 합니다.

반응형

메타데이터, 데이터 바인딩, 서비스

메타데이터 클래스를 처리하는 방법을 Angular에게 알려줍니다. app.component.ts파일에서 클래스를 만들었습니다.
데코레이터(Decorator)는 함수(function)이며, 데코레이터는 무엇을 할지 클래스에 알려줍니다.

@Component({
  selector: 'my-component',
  templateUrl: 'app/app.component.html',
  directives: [HighlightDirective]
})
export class MyComponent {
    public name: String;
    public today: Date;

    constructor() {
        this.name = 'Angular 2 Rocks !';
        this.today = new Date();       
    }
    sayMyName() {
        alert (this.name);
    }
}

여기서 @Component는 데코레이터 입니다. 이 함수에서는 클래스를 구성하는 매개변수를 전달합니다. 데코레이터에 전달하는 파라미터들은 다음과 같습니다.

selector : Angular 에서 바인딩할수 있는 CSS 선택
templateUrl : 템플릿 파일의 위치
directives : 템플릿에 바인딩 할 수 있는 디렉티브 배열
providers : 서비스를 의해 의존관계 주입자들(dependency injection providers)의 배열

데이터 바인딩 방법

데이터바인딩을 사용하면 템플릿의 데이터 구성요소에 바인딩 할 수 있습니다. 데이터 바인딩 형식에는 다음 네가지가 있습니다.

  1. DOM에 다가
  2. DOM에서 직접
  3. 1,2 번 둘다
  4. 속성 및 이벤트 바인딩을 사용하여 속성과 이벤트 바인딩을 결합한 양방향 데이터 바인딩 ngModel

단방향 바인딩

다음 코드를 한번 봅시다

<h1>{{today | date:"fullDate"}}</h1>

<div>
    <button (click)="sayMyName()" myHighlight>Do Something Special</button>
</div>

app.component.html파일 안에서 {{today}}app.component.ts 파일의 today 프로퍼티를 단방향 바인딩을 통해 바인딩하고 있습니다. sayMyName() 함수는 click 이벤트 핸들러에 바인딩 됩니다.

양방향 바인딩

양방향 바인딩을 시연하려면 app.component.html 파일에 <div> 태그를 포함하도록 변경하세요.

<div>
    <input [(ngModel)]="task">
</div>
<div>
    {{task}}
</div>

app.component.ts 파일에서는 아래와 같이 비슷하게 변경해 줍니다.

export class MyComponent {
    public name: String;
    public today: Date;
    public task: string;

    constructor() {
        this.name = 'Angular 2 Rocks !';
        this.today = new Date();
        this.task = '';
    }
    sayMyName() {
        alert (this.name);
    }
}

여기서는 task 프로퍼티에 바인딩했습니다. 사용자가 입력 할 때 입력 내용이 페이지에 나타납니다.

서비스 만들기

Angular2의 서비스는 정의 된 함수가 있는 클래스를 말합니다.무엇이든 서비스가 될 수 있습니다.
JS 파일에 저장된 작업 목록을 읽는 서비스를 작성해 보겠습니다.

/app폴더에 task.service.ts라는 파일을 만들고 다음 파일 추가해 보겠습니다.

import {Injectable} from 'angular2/core';

@Injectable()

export class TaskService {
}

Angular Injectable함수를 포함하고 이 함수를 @Injectable() 데코레이터에 적용했습니다.
TypeScript는 @Injectable 데코레이터를 보고 Angular가 이 서비스에 다른 종속성 주입을 하는데 필요한 메타 데이터를 방출합니다.

작업을 위한 모델을 만들어 보겠습니다.
/app폴더에 tasks.ts라는 새 파일을 만듭니다. 이 파일에서 우리는 다음과 같이 작업을 위한 모델을 생성할 것입니다.

export class Task {
  id: number;
  name: string;
}

JavaScript 배열을 사용하여 새 파일을 만듭니다. 이 파일은 sample.tasks.ts로 다음 내용을 추가 합니다.

import {Task} from './tasks';
export var TASKS: Task[] = [
    {"id": 11, "name": "Buy Bread"},
    {"id": 12, "name": "Buy Milk"},
    {"id": 13, "name": "Buy Soap"}
];

모델을 이 파일에 포함시켰고 이 모델을 가진 배열을 ㅁ나들었습니다. 이 배열은 다음과 같이 TASKS로 내보내집니다.

task.service.ts파일에서 우리는 이 클래스를 포함하고 GET 메소드를 생성할 것입니다. 서비스 파일의 내용을 다음 코드로 바꿉니다.

import {TASKS} from './sample.tasks';
import {Injectable} from 'angular2/core';

@Injectable()

export class TaskService {
  getTasks() {
    return TASKS;
  }
}

모델로 서비스와 데이터를 생성했습니다. 이제 템플릿과 구성 요소를 수정해야 합니다. app.component.ts 파일을 다음과 일치하도록 수정하세요.

import {Component} from 'angular2/core';
import {HighlightDirective} from './highlight.directive';
import {TaskService} from './task.service';
import {Task} from './tasks';

@Component({
  selector: 'my-component',
  templateUrl: 'app/app.component.html',
  directives: [HighlightDirective],
  providers: [TaskService]

})
export class MyComponent {
    public name: String;
    public today: Date;
    public task: String;
    public taskList: Task[];



    constructor(private _taskService: TaskService) {
        this.name = 'Angular 2 Rocks !';
        this.today = new Date();       
        this.task = '';
        this.taskList = this._taskService.getTasks();

    }
    sayMyName() {
        alert (this.name);
    }
}

service 와 tasks 를 포함 시켰습니다.

import {TaskService} from './task.service';
import {Task} from './tasks';

service 를 가능하게 하려면 공급자가 가능해야 합니다. 그래서 @Component 데코레이터에 다음 코드를 넣었습니다.

providers: [TaskService]

service 가 컴포넌트에 노출이 됩니다. taskList를 포함할 배열을 생성하고 Task 유형으로 만듭니다.

export class MyComponent {
    public name: String;
    public today: Date;
    public task: String;
    public taskList: Task[];

    constructor(private _taskService: TaskService) {
        this.name = 'Angular 2 Rocks !';
        this.today = new Date();       
        this.task = '';
        this.taskList = this._taskService.getTasks();

    }
    sayMyName() {
        alert (this.name);
    }
}

생성자에 service에 연결하여 개인 변수에 할당하는 정의가 포함되어 있습니다. 밑줄은 데이터가 외부로 전달되고 있음을 빠르게 확인 할 수 있도록 하기위해 사용됩니다.
this._taskSerivce.getTasks()메소드를 사용하면 서비스 파일에 작업을 가져올 수 있습니다.

app.component.html파일에 다음을추가합니다.

<div>
    <ul>
        <li *ngFor="#item of taskList">{{item.name}}</li>
    </ul>
</div>

*ngFor 다이렉티브를 사용하면 taskList배열을 신속하게 반복할 수 있습니다.

반응형

Angular2 컴포넌트, 디렉티브, 템플릿

이전 코드를 복제하기

Angular2 시작하기에서 Hello World 를 완료했습니다.

이전의 코드를 확장해서 구성요소, 모듈, 템플릿 작업을 해보도록 하겠습니다.

ng2-todolist 폴더를 만들고, 기존에 있던 코드들을 복사합니다.

 # cp -R ng2-helloworld ng2-todolist

package.json파일안에 "name"을 변경합니다.

"name": "ng2-todolist", 

index.html파일안에 title을 변경합니다.

<title>Angular 2 - My Todo List</title>

컴포넌트의 재사용

컴퐤넌트는 페이지에서 다른 요소를 만들고 정의하는 방법입니다. Angular 1에서는 디렉티브, 컨트롤러를 사용하여 컴포넌트 안에서 디렉티브을 찾도록 기능을 구현해야 했습니다.

app/app.component.ts파일을 수정해 보겠습니다.

import {Component} from 'angular2/core'

@Component({
  selector: 'my-component',
  template: '<div><button (click)="sayMyName()">Do Something Special</button></div>'
})
export class MyComponent {
    public name: String;
    constructor() {
        this.name = 'Angular 2 Rocks !';
    }
    sayMyName() {
        alert (this.name);
    }
}

class AppComponent 이름을 MyComponent 로 변경 하였기 때문에 index.html,main.ts 파일안의 내용을 변경해야 합니다.

<my-component>Loading...</my-component>

main.ts 파일 안에 다음으로 수정합니다.

import {bootstrap}    from 'angular2/platform/browser'
import {MyComponent} from './app.component'

bootstrap(MyComponent)

서버를 실행 시켜 봅니다. 버튼과 버튼을 눌렀을 경우에 경고창이 나오는 것을 확인할 수 있을것입니다.

 # npm start

Imgur

디렉티브 사용하기

app폴더에 highlight.directive.ts파일을 만들고 다음 내용을 추가 합니다.

import {Directive, ElementRef} from 'angular2/core';
@Directive({
    selector: '[myHighLight]'
})
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'orange';
    }
}

Directive : @directive 데코레이터를 위해 사용
ElementRef : DOM element 에 엑세스 할 수 있도록 허용합니다.

highlight.directive.ts파일을 다음과 같이 변경합니다.

import {Directive, ElementRef} from 'angular2/core';
@Directive({
    selector: '[myHighlight]',
     host: {
    '(mouseenter)': 'onMouseEnter()',
    '(mouseleave)': 'onMouseLeave()'
  }
})
export class HighlightDirective {
    private _el:HTMLElement;
    constructor(el: ElementRef) { this._el = el.nativeElement; }
    onMouseEnter() { this._highlight("yellow"); }
    onMouseLeave() { this._highlight(null); }
    private _highlight(color: string) {
        this._el.style.backgroundColor = color;
    }
}

host : MouseEnter, MouseLeave에서 CSS 변경을 수행하기 위해 호출할 두가지 메소드가 포함되어 있습니다.

템플릿의 위력

Angular는 템플릿을 사용해서 컴포넌트 안에서 클라이언트가 보는 것을 관리합니다. 템플릿에는 보여지기 위한 HTML 코드가 포함되어 있습니다. <script> 태그는 제외 한 대부분 모든 HTML 태그들을 템플릿에서 사용할 수 있습니다.
<html>,<body>,<base>와 같은 태그들을 사용할수는 있지만 실제로 템플릿에는 실제로 적용되지 않고 무시됩니다.
컴포넌트에 템플릿을 추가 하려면 템플릿 테그를 제거하고 templateUrl이라는 테그를 사용합니다.

templateUrl : 템플릿의 경로를 말합니다.

import {Component} from 'angular2/core'
import {HighlightDirective} from './highlight.directive';

@Component({
  selector: 'my-component',
  templateUrl: 'app/app.component.html',
  directives: [HighlightDirective]
})
export class MyComponent {
    public name: String;
    constructor() {
        this.name = 'Angular 2 Rocks !';
    }
    sayMyName() {
        alert (this.name);
    }
}

npm start를 사용하고 있다면 백그라운드에서 코드변경이 자동으로 브라우저에 적용되는 것을 확인할 수 있습니다.

간단히 날짜를 적용해 보겠습니다.
public today:Date 을 추가하고 new Date()를 추가해 봅니다.

app.component.ts부분을 아래와 같이 수정해 봅니다.

export class MyComponent {
    public name: String;
    public today: Date;

    constructor() {
        this.name = 'Angular 2 Rocks !';
        this.today = new Date();       
    }
    sayMyName() {
        alert (this.name);
    }
}

이제 app.component.html파일을 만들고 날짜가 표기 되도록 만들어 봅니다.

<h1>{{today | date:"fullDate"}}</h1>
| 표시
| 표시는 앵귤러1의 필터를 대체하는 파이프입니다. 필터처럼 템플릿 출력 형식을 지정하는데 도움이 됩니다.
반응형

Angular2 를 준비하기

Angular 2 와 Angular 1.x 차이

JavaScript를 기반으로하는 스크립트 언어.

Angular 1.x에 대한 지식이 필요하지 않지만 JavaScript, Node.js 및 npm에 대한 지식이 필요합니다.

Angular 2 는 TypeScriptECMA6 를 포함하고 있습니다.

기존에는 Angular 1.x 를 공부하면 됐지만, 이제는 typescript에 대해서 공부를 해야합니다. 또다른 자바스크립트를 공부하는 느낌입니다.
자나깨나 여러가지 언어를 혼합해서 사용하고 있는데, 이제는 점점 더 정리가 안되고 있습니다.

TypeScript는 JavaScript 확장을 돕기 위해 마이크로소프트에서 개발한 무료 오픈 소스 언어입니다. 고급 자동완성, 탐색 및 리팩터링을 제공합니다. 자세한 내용은 https://www.typescriptlang.org/ 에서 확인 할수 있습니다.

ECMA6는 클래스 및 모듈을 사용할 수있게 해주는 JavaScript 의 표준입니다. http://es6-features.org/ 를 참조하면 됩니다.

개발툴

Microsoft 의 Visual Studio Code 을 추천합니다.

기본적으로 마소에서 만들었기 때문에 TypeScript 언어를 잘 지원하고 있습니다. 개인적으로 Atom.io보다 최적화가 잘되어 있다고 생각합니다.
Atom 은 참여하는 사람들이 많아서 다양한 기능들을 찾을 수 있지만, 어수선합니다. 처음에는 Atom 으로 시작을 했지만, 지금은 Visual Code 에 정착해서 사용하고 있습니다.

폴더세팅

응용 프로그램을 시작하고 실행하기 위한 준비가 되었습니다.

package

package.json을 만들어서 npm 세팅을 하면 되지만, 다음과 같이 하면 기본세팅으로 자동설정이 됩니다.

# npm init --yes

그리고 아래 들어있는 내용은 아래와 같은 내용입니다.

{
  "name": "ng2-helloworld",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

새로운 파일 tsconfig.json을 만듭니다.

# touch tsconfig.json

안에 내용을 다른과 같이 작성합니다.

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ]
}

이 파일 대부분은 TypeScript 응용 프로그램의 기본 구성입니다. tsconfig.json파일을 처리하는 방법에 대해서 컴파일러에 알져주는 역할을 합니다.
noImplicitAny 변수는 컴파일러에게 변수 선언을 처리하는 방법을 알려줍니다. false로 설정을하면 기본 유형을 any로 설정할 수 있으므로 Angular 2 를 좀 더 쉽게 학습할 수 있습니다.

tsconfig.json에 대한 문서

새로운 파일 typings.json을 만들고 다음 내용을 추가 합니다.

{
  "ambientDependencies": {
    "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd",
    "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd"
  }
}

새로운 파일 package.json파일을 만들고 아래 내용을 추가합니다.

{
  "name": "ng2-helloworld",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "typings": "typings",
    "postinstall": "typings install"
  },
  "license": "ISC",
  "dependencies": {
    "angular2": "2.0.0-beta.14",
    "systemjs": "0.19.25",
    "es6-shim": "^0.35.0",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.2",
    "zone.js": "0.6.6"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "lite-server": "^2.2.0",
    "typescript": "^1.8.9",
    "typings":"^0.7.12"
  }
}

tsc : 타입스크립트 컴파일러
lite : 실시간으로 파일변경을 감지해서 브라우저에 반영. 앵귤러 앱을 시작하기 위한 위한 파일 서버
typings : typings 툴을 시작
postinstall : npm 설치후에 타이핑 설치 method 실행

여기서 npm install 명령을 실행하셔야 문제가 없습니다.

 # npm install

npm manager 는 진리입니다. 그런데, 최근에는 비슷한 소스 이름으로 올려서 개인정보를 훔쳐가는 일이 발생했다고 하는데, npm install명령을 사용할때 소스 이름을 잘 파악해서 사용해야 되겠습니다.

이제 /app라는 하위폴더를 만들고 다음을 실행합니다.

 # mkdir app
 # cd app

컴포넌트(component) 파일 app.component.ts파일을 생성하고, 아래와 같은 내용을 입력합니다.

import {Component} from 'angular2/core';

@Component({
    selector: 'my-app',
    template: '<h1>Hello World !</h1>'
})
export class AppComponent { }

이파일은 컴포넌트의 루트 컴포넌트(root component) 파일입니다.
이 파일 안에는 angular2/core 모듈을 가져오는 import와 메타 데이터 객체를 가져오는 @Component데코레이터가 있습니다.
export class Appcomponent{}은 메인 어플리케이션을 가져오기 위해서 사용하는 빈 클래스 입니다.

이제 Angular가 방금 생성 한 구성 요소 파일을 로드 할 수 있도록 파일을 만들어야 합니다.

main.ts라는 파일을 만들고, 파일이 /app폴더에 있는 것을 확인하고 다음 코드들을 입력합니다.

import {bootstrap} from 'angular2/platform/browser'
import {AppComponent} from './app.component'

bootstrap(AppComponent)

bootstrap : 사용하기로 결정한 플랫폼을 기반으로해서 컴포넌트 로딩을 처리합니다.

다시 package.json 이 있는 폴더로 돌아옵니다.

index.html파일을 만들고 다음 코드를 입력합니다.

<html>
  <head>
    <title>Angular 2 Hello World</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <script src="node_modules/es6-shim/es6-shim.min.js"></script>
    <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
    <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>

    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
  </head>

  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

지금까지 아래와 같은 폴더 구성을 갖고 있을겁니다.

Imgur

다음을 실행해서 제대로 되었는지 확인해 봅닌다.
문제가 없다면 다음과 같은 화면이 나오는 것을 확인 할 수 있습니다.

Imgur

반응형

안드로이드 HTML 파싱하기

JSoup을 사용해서 하면 간단하게 사용할 수 있다.

자바에서도 위에 사용하는 소스를 통해서 이요할 수 있지만, 안드로이드를 통해서 사용할 것이기 때문에 Gradle 을 통해 설치를 해 보겠다.

gradle 의 build.gradle (Module: app) 에 아래와 같은 문구를 추가합니다.

// jsoup HTML parser library @ https://jsoup.org/
compile 'org.jsoup:jsoup:1.10.3'

그리고 Gradle Sync Now를 눌러주는 것을 잊으면 안됩니다. 그래야 적용이 됩니다.

주의할점
메인화면에서 네트워크 연결을 사용하면 에러가 납니다. 메인에서 네트워크 연결을 바로 시도 하면 에러가 납니다. 이 때문에 하루를 날려 버렸습니다.

여러 예제를 보면 다들 AsyncTask를 통해서 이용하고 있습니다. 사용법도 간단하고, 예제도 있지 때문에 저도 같은 방법을 사용할 것입니다.

AsyncTask에 대한 설명이 필요하시면 IT 마이닝 블로그로 이동하기

class MainActivity 아래에

다음과 같은 코드를 추가 합니다.


private class MainPageTask extends AsyncTask<Void,Void,Void> {
    private Elements element;

    @Override
    protected void onPostExecute(Void result) {
        //doInBackground 작업이 끝나고 난뒤의 작업
        mainHello.setText(element.text());
    }

    @Override
    protected Void doInBackground(Void... params) {
        //백그라운드 작업이 진행되는 곳.
        try {
            Document doc = Jsoup.connect("http://example.com").get();
            element = doc.select("#algoList > tbody");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

사이트 example.com 를 파싱하려고 합니다.

doInBackground에서 작업을 하고 onPostExcute에서 결과가 끝나고 난 뒤의 작업을 수행합니다.

doInBackground에서 작업을 처리하려고 하면 오류가 납니다. 다른 메소드에 입력 하시는 것을 잊으면 안됩니다.

반응형

+ Recent posts