[AngularJS] MVC Pattern in Angular

Posted in 모바일/Javascript // Posted at 2016. 7. 10. 11:41

MVC(Model-View-Controller)는 아주 오래된 SW아키텍처패턴이다.
(이 패턴이 소개된 시기는 1979년으로, 길지 SW공학분야에서는 고전적인 패턴이라 할 수 있다.)

이 패턴은 백엔드개발자(웹서버 사이드 개발자)에게는 이미 익숙한 패턴일 것이다.

자바의 JSP(스트럿츠), 서블릿, Bean 등의 상호연동 구조가 MVC 모델에 기반하고 있으며, 닷넷은 자사 웹개발플랫폼 기술 이름 자체를 ASP.NET MVC로 하여 MVC 구조를 지향하고 있다.

그러니, 그들(웹서버 사이드 개발자)이 이 패턴에 익숙한 것은 당연한 것이다.

반면, 웹 프론트엔드 개발자에게는 조금 낯설수도 있다.
물론 자바스크립트를 코어하게 학습하거나, ExtJS/Sench Touch와 같은 MVC 모델에 기반한 프레임워크를 다뤄본 적이 있다면, 역시 익숙한 개념일 것이다. (그래.. 중요한 것은 익숙함의 차이인 것이다.)

이 패턴의 핵심은, 모델이 어쩌구.. 뷰가 어쩌구가 아니다. 바로 기저에 깔린 사상이다.
그 사상이 바로 '관심사의 분리(관점의 분리)를 통한 상호 독립성 보장'인 것이다.

웹 프론트개발자 관점에서도 '관심사의 분리'라는 사상 자체는 너무나도 자연스러운 개념일 것이다.
바로 HTML과 CSS 그리고 Javascript의 역할 분리를 빗대어 보면 알 수 있다.

흔히 이 셋의 역할을 'HTML(구조)-CSS(표현)-Javascript(동작)'로 정의한다. 이것이 바로 역할의분리, 다시말해 관심사의 분리이며 이렇게 분리된 구조를 통해 상호 독립적인 개발이 보장되어 생산성과 유지보수성 등이 좋아지게 되는 것이다.

MVC 모델 역시 이와같은 관심사의 분리라는 SW공학적 원리가 적용된 아키텍처 패턴인 것이다.

* MVC 패턴
- 대부분의 응용프로그램은 데이터가 사용되며 이 데이터를 기반으로 사용자 인터페이스를 제공한다. MVC패턴은 데이터를 조작하는 비즈니스 로직과 사용자인터페이스를 서로 분리하여 상호 영향 없도록 하는 것에 초점을 맞춘 패턴이다. 이 둘(데이터와 인터페이스)의 상호연동을 위해 컨트롤러라는 새로운 계층을 두고 있는 것이다.

- Model: 응용프로그램의 핵심 로직과 데이터를 캡슐화 수행
- View: 사용자가 보게 되는 인터페이스의 총칭. 모델의 정보를 표시하는 역할수행
- Controller: 모델과 뷰의 연결을 위한 계층으로 사용자 입력을 받아 중계 수행

MVC 패턴에 대한 이론적 내용은 많은 인터넷 자료에서 쉽게 찾아 볼 수 있으니 여기서는 그만 다루도록 한다. 혹여 MVC라는 용어가 어색한 웹 프론트 개발자들이 반드시 짚고 넘어가야 할 점은, MVC는 관점의 분리라는 공학적 원리가 응용프로그램의 구조와 상호작용 부분에 적용된 모범사례라는 것 뿐이다.

* Server Side MVC? Client Side MVC?
- 웹개발 측면에서 보면, MVC 패턴은 웹 서버 사이드 개발에서의 응용프로그램의 구조 패턴으로 먼저 보편화되었다고 할 수 있다. 즉 JSP나 ASP.NET과 같은 서버 측 응용구조로 채택되어 지금까지도 많이 활용되고 있는 패턴이다.

그러나 오늘날 진보적인 웹 클라이언트 개발에 훌륭한 자바스크립트 라이브러리들이 등장하고 이 들이 추구하는 아키텍처 기반 구조 역시 MVC에 근거하고 있다.

전통적인 서버측 개발에서의 View의 영역은 (최종 랜더링되는) HTML 페이지이다. 즉 Controller와 Model은 서버측에 존재하며 (서버가 사용자에게 반환하는) HTML페이지가 바로 View의 영역이 되는 것이다.

이 말은 웹 클라이언트에 존재하는 웹 클라이언트 자체가 View가 된다는 것인데, 웹 클라이언트 영역에서도 이 부분을 다시 MVC로 나누고 있는 것이다. 뭔가 혼란스럽지 않은가?

웹 응용프로그램이란 것이 결국 서버측과 클라이언트 측이 결합되어 하나의 결과물이 되는 것인데, 각각의 영역에서 MVC 패턴을 따로 다룬다면, 전체의 MVC모습은 어떻게 된다는 말인가?

이것은 어떻게 보면 중요한 문제가 될 수 있다. 분업화된 작업방식(서버개발자/클라이언트 개발자)에서 각기 나름의 MVC 모델을 추구한다면 응용프로그램의 전체 구조는 가히 우스운 꼴이 될 수도 있다.

오히려 이 부분은 웹 프론트앤드 개발자에게는 익숙한 것일지도 모른다. 그것은 웹 응용프로그램의 구현모델의 차이를 이해하면 되는 것이다.

* SPA(Single Page Application)에서의 MVC
- 서버측 MVC, 클라이언 측 MVC라는 말 자체가 조금 억지스럽다. 그것은 응용프로그램의 구현모델상의 차이가 날 수 있는 부분이지, 서버와 클라이언트로 구분되지는 않을 것이다.

AngularJS는 SPA 모델을 위한 자바스크립트 프레임워크이다.
SPA는 전통적인 웹 구조와 상반되는 개념으로, 기존의 웹 페이지는 데이터를 전송하고 서버가 이를 처리한 후 완전히 새로운 페이지를 랜더링하는 구조였다.(이를 '호출 후 새로고침' 방식이라 한다)

그러나 현대의 웹 페이지는 단순히 정적 페이지라는 개념을 넘어 사용자의 이벤트에 반응하고 적절한 상호작용을 제공하며 애니메이션과 네비게이션을 자체적으로 해결하는 응용프로그램의 면모를 보여줄 수 있다. 그리고 원격지 서버와의 통신은 더이상 완전히 새로운 페이지의 '새로고침'이 아니라 단일 페이지에서 필요한 데이터만 비동기로 가져와서 사용자의 작업을 방해하지 않으면서 데이터를 갱신시킨다.

결론적으로 전통적인 새로고침 방식의 웹과 SPA 방식의 웹에서의 MVC의 역할 모델이 조금 상이할 수 있다고 할 수 있다.

다시 말하지만, AngularJS는 SPA 실현을 가능케 하는 자바스크립트 프레임워크이다.
SPA모델에서는 대부분의 작업이 클라이언트 측에서 이루어진다. 그리고 서버측 데이터 연동은 Ajax와 같은 통신 모델을 이용하여 비동기로 그때그때 필요한 데이터만 가져와서 사용자 화면을 갱신시킨다. 이런 모델에서의 MVC패턴의 각 영역은 다음과 같다.

- Model: View가 사용할 데이터 또는 공통되고 주요한 비즈니스 로직을 정의한 영역으로 실제 데이터는 대체로 서버측에 존재하게 된다.
- View: 사용자 화면을 구성하는 HTML 영역
- Controller: 뷰와 모델을 연결해 주는 영역으로 SPA모델에서는 클라이언트 측에 존재하게 된다. 좀 더 면밀히 따져보자면, SPA 모델에서는 Controller의 영역을 ViewModel(뷰모델)로 설계되기도 하며, 이는 SPA뿐만 아니라 전통적인 윈도우 응용프로그램(요청과 응답 구조의 웹구조가 아닌) 환경에서 뷰와 모델간 의존성을 제거하고 뷰의 상태와 뷰에 투영될 데이터의 변화에 따른 자동 바인딩을 가능케 하는 구조로써 이와 같은 모델을 MVC의 변형된 모델로 MVVM 패턴이라고 불리운다.

큰 틀에서 정리하자면, Model은 그 역할이, 응용프로그램 전체에 걸쳐 필요한 데이터와 비즈니스 로직을 제공하게 되는데, SPA 구조에서는 이 부분을 클라이언트 측에 추상화 하여 일종의 공용서비스 형태로 구현하며, 실제 데이터는 서버로부터 비동기 형태로 (백그라운드에서) 받아와서 추상화된 서비스계층에 할당하고 뷰모델이라는 중간계층을 경유해 뷰와 바인딩시키는 구조인 것이다.

결국 SPA 에서의 서버측은 응용프로그램에 필요한 데이터를 비동기로 서비스 해 주는 기능만 존재하면 된다는 말이다.(이부분은 대체로 REST API로 구현된다)

SPA모델에서의 MVC는 기존의 새로고침 모델에서의 MVC와는 그 역할에 따른 컴포넌트의 위치와 통신구조에서 차이점을 보이며, 어떤 형태의 모델로 웹 응용프로그램을 구현하는지에 따라 '모델-뷰-컨트롤러'의 실질적 구현레벨의 모습이 약간 다를 수 있다는 것이다.

하지만 관점의 분리라는 사상과 비즈니스 로직(모델)과 뷰를 분리하는 아키텍처 구조는 SPA이든 새로고침방식이든 다르지 않다는 것은 원론적으로 중요하다.

* AngularJS의 MVC 컴포넌트
- AngularJS에서는 MVC 패턴을 기반으로 응용프로그램 구성을 가능케 한다. 어떤이는 MVVM이라 예기하고 싶겠지만 여기서는 상황을 일반화 시켜서 글을 이어 나가도록 한다. MVVM역시 MVC에서 필요에 의해 일부 변형시킨 패턴이며 이 글에서는 그 차이가 그리 중요하지 않기 때문이다.

(실제로 AngularJS는 자신의 아키텍처 기반을 MVW(Model-View-Whatever)라고 부르며 Whatever란 어떤것이라도 가능하다는 뜻으로, MVC/MVP/MVVM 모두 가능하다는 의미이다. 아키텍처 패턴간 발전과정과 특징 및 구조적 차이는 분명이 존재하며 이 들의 관계는 다른 글에서 다시 언급하도록 한다.)

MVC 아키텍처를 위해 AngualrJS가 제공하는 컴포넌트를 알아보자. 다음은 AngularJS 공식 사이트에서 설명하는 내용이다.

* Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties are accessed through bindings.
* View — The template (HTML with data bindings) that is rendered into the View.
* Controller — The ngController directive specifies a Controller class; the class contains business logic behind the application to decorate the scope with functions and values

 AngularJS가 MVC 구현을 위해 제공하는 것중 핵심은, ngController 디렉티브이며 이를 이용하여 뷰를 위한 컨트롤러 클래스를 생성할 수 있다.

Model은 scope의 프로퍼티라고 설명하고 있다. AngularJS에서 $scope은 뷰와 컨트롤러의 연동을 위해 제공되는 객체이며 컨트롤러 객체에서 뷰로 데이터를 노출하기 위한 일반적인 방법을 제공한다.
scope이 모델이다라고 애매한 해석을 하기 보다는, 컨트롤러에서 모델 정보를 뷰로 연결하기 위해 제공되는 객체로 이해하면 될 것이다.

실제 예제를 한번 보자.

<div ng-app ng-init="qty=1;cost=2">
  <b>Invoice:</b>
  <div>
    Quantity: <input type="number" min="0" ng-model="qty">
  </div>
  <div>
    Costs: <input type="number" min="0" ng-model="cost">
  </div>
  <div>
    <b>Total:</b> {{qty * cost | currency}}
  </div>
</div>

코드는 뷰와 모델간 가장 기본적인 상호작용을 설명하기 위해 작성되었으며, 데이터에 해당하는 Model정의를 위해 ng-model 디렉티브를 사용했다. ng-model 디렉티브가 지정된 입력박스의 값은 자동으로 $scope객체의 프로퍼티로 정의되며, 더블중괄호로 표현되는 '{{ property of scope }}' 표현식을 통해 모델의 정보를 View로 연결키실 수 있다.

다음 이에 대한 설명으로 AngularJS 공식 사이트에서 제공하는 그림이다.

 

이제 컨트롤러를 등장시켜 보자.

angular.module('myModule', [])
.controller('InvoiceController', function() {
  this.qty = 1;
  this.cost = 2;
  this.total = function total(outCurr) {
    return this.qty * cost;
  };
  this.pay = function pay() {
    window.alert("Thanks!");
  };
});

<div ng-app="myModule" ng-controller="InvoiceController as invoice">
  <b>Invoice:</b>
  <div>
    Quantity: <input type="number" min="0" ng-model="invoice.qty" required >
  </div>
  <div>
    Costs: <input type="number" min="0" ng-model="invoice.cost" required >
  </div>
  <div>
    <b>Total:</b>
    <span>{{invoice.total}}</span>
    <button class="btn" ng-click="invoice.pay()">Pay</button>
  </div>
</div>

컨트롤러는 뷰가 바인딩하고 다룰 수 있는 속성과 메서드를 정의하기 위한 객체로써 AngularJS 모듈에 연결한다. 코드를 보면 $scope 객체를 찾아볼 수 없는데 이는 controller-as 문법을 사용하여 $scope객체를 명시적으로 사용하지 않아도 되기 때문이다. 중요한 것은 View와 Scope 그리고 Controller의 상호작요이며 다음 그림에 도식화하여 설명하고 있다.

 

* 일반적인 MVC 패턴 구현
- 이제 AngularJS에서 일반적 MVC 패턴 구현의 전체 모습을 살펴보자. Model의 경우 원격지 서버에 존재하는 데이터를 기반으로 하는게 일반적이며 이와같은 공통적인 데이터를 AngularJS 어플리케이션 전체에 공유하기 위해서는 AngularJS의 Service(서비스) 객체로 생성하는 것이 좋다.

사실 이전까지의 글보다 다음의 코드를 이해하고 이 코드를 기반으로 AngularJS MVC 패턴 구현을 이해하는 것이 보다 현실적이다.

먼저index.html을 다음과 같이 작성한다

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="app.js"></script>
<body>
 <div ng-app="myModule" ng-controller="MainCtrl as main">
  <h1>Persons</h1>
  <ul>
     <li ng-repeat="person in main.persons">
        {{person.name + ', ' + person.city}}
     </li>
   </ul>
 </div>
</body>
</html>

AngularJS 관련 자바스크립트 파일을 app.js라는 별도의 파일로 분리했다.
그리고 AngularJS의 모듈과 컨트롤러를 매핑시킨다. 이때 $scope객체를 사용하는 대신, controller-as 문법을 사용한다. 그리고 배열로 반환되는 persons 정보를 ng-repeat 디렉티브로 순환시켜 <ul>태그의 <li>항목으로 각각 매핑시킨다.

그리고 다음은 app.js 파일의 코드이다.

//모듈 생성
var app = angular.module('myModule', []);
 
//컨트롤러 생성(컨트롤러 생성자에 PersonModel서비스 전달=>의존성주입(생성자 주입)패턴)
app.controller('MainCtrl', function(PersonModel){
 var main = this;
 //Personmodel서비스에 정의된 getPersons()함수를 호출
 main.persons = PersonModel.getPersons();
});

//서비스 생성
//서비스는 전체 어플리케이션에서 사용하게 될 데이터나 공통 기능을 작성하기 좋은 곳이다
//보통 MVC의 Model 정보를 원격지에서 불러오는 역할을 하도록 한다.
 app.service('PersonModel', function(){
   var service = this;

  //실제환경에서는 persons 정보는 원격지 서버로 부터 받아오는 것이 일반적이지만,
  //여기서는 코드의 단순화를 위해 직넙 객체 리터럴로 생성한다.
   var persons = [
       {name: 'Park', city: 'Pusan'},
       {name: 'KIM', city: 'Seoul'},
       {name: 'Jung', city: 'suwon'}
     ];
    
   service.getPersons = function(){
     return persons;
   };

   service.setPersons = function(){
     //서버로 부터 받아서 업데이트

   };
});

Model 정보를 제공하는 서비스 객체(PersonModel)를 생성하여 컨트롤러 생성자 함수에 주입시킨다. 이렇게 함으로써 Controller와 Model을 물리적으로 분리가능하며 의존성 주입패턴으로 이 둘을 의존성을 관리한다. 컨트롤러는 이제 PersonModel의 속성과 메서드를 사용할 수 있게 되었다.

참고로 서비스와 컨트롤러에서 this키워드를 변수에 저장시키는 것은, 자바스크립트의 동적언어 특징에서 기인하는 문맥(Context)상 this의 해석이 모호해 지는 점을 예방하기 위해 명시적으로 할당해 두는 것이다. 이는 예외적인 동작에 대한 예방차원에서 필요한 코드로 자바스크립트 특징에 기반한 코드사례이다.

결과 화면은 다음과 같다.

 

지금까지 AngularJS의 MVC 패턴 구현에 대해 장황하게(?) 알아보았다.

대부분의 AngularJS 응용프로그램의 코드 구조는 여기에 살을 더 붙여 나가는 식으로 작성하면 된다. MVC 패턴에 기반한 응용프로그램 구조는 영역간 분리를 통해 상호 독립적 개발과 유지, 단위테스트를 가능케 하여 전체적인 생산성과 유지보수성을 향상시킨다.

중요한 것은 MVC의 사상을 이해하고 AngularJS가 MVC를 위해 제공하는 컴포넌트를 적절히 조합하여 응용프로그램을 구성하는 것이다.

이 글을 바탕으로 좀더 세말한 치장을 해 나가면 될 것이다.

'모바일 > Javascript' 카테고리의 다른 글

[AngularJS] Module  (0) 2016.07.12
[AngularJS] Two-way Data Binding  (0) 2016.07.10
[AngularJS] 일주일 탐방기  (0) 2016.07.06
knockout.js  (0) 2013.11.14
OOP in Javascript  (0) 2013.08.16

[AngularJS] 일주일 탐방기

Posted in 모바일/Javascript // Posted at 2016. 7. 6. 11:23

오랜만에, 웹 클라이언트 기술에 다시 불을 지펴보고 싶어졌다.

일주일 전, AngularJS를 본격적으로 알아보고자 책 한권 구입해서 대략 전체를 한번 훑어봤다.


기술사 공부할때, Node.JS와 함께 기출 예상되었던 핫(hot)한 자바스크립트 프레임워크 중 하나여서 대략 느낌(?) 정도만 알고 있었는데, 알면 알 수록 매력 떵어리가 아닌가...

특히 CRUD기반의 SPA(Single Page Application) 개발을 위한 최고의 생산성을 보장하는 아주 훌륭한 물건이라 하겠다.

더불어 이젠 전통에 가까워진 MVC(Model View Controller) 아키텍처 사상에 기반을 둔 프로그램 구조를 채택하고 있어 분할과 정복/관심사의 분리라는 소프트웨어 기본 원리가 적용되어 구현의 독립성, 단위테스트의 용이성, 느슨한 결합으로 연결된 전체적인 아키텍처는 유지보수성을 향상시켜 엔트프라이즈급 웹 응용개발에 아주 적합해 보인다.

참고로 AngularJS는 MVW(Model View Whatever)라는 용어로 MVC를 넘어 MVP, MVVM. 뭐든지 다... 라는 발찍한(?) 도발마저 하고 있다.

View와 Model간의 관계성과 중간 연결계층인 Controller의 View와의 차수성이 이들 아키텍처를 나누는 주요 기준이 되는데, 이 부분은 좀 더 면밀히 따져 봐야 할 것 같다.

AngularJS는 아주 유명한 크로스브라우저 라이브러리인 jQuery와 자주 비교되는 사실을 발견했다.

음.. 그 목적과 쓰임새가 분명 다르다는 느낌을 지울 수 없지만, 이 둘이 많은 자료에서 매번 비교되는 것은 jQuery가 이미 산업표준으로 자리매김을 해 버린 웹클라 개발환경에 불현듯(?) 나타나 상승세를 타버린 AngularJS의 유명세와의 시기적 마찰이 그 시발점인 듯 하며 실제로 jQuery로 구현된 많은 부분이 AngularJS로 대체가능 하다는 사실도 한 몫했을 터이다.

앞서, 구매한 책에서는 다음과 같이 이 둘을 언급하고 있다.

수많은 프레임워크들 중에서도 jQuery가 압도적인 지지를 받는다는 점에 대해서는 많은 개발자가 동의할 것이다. jQuery가 수많은 브라우저의 각기 다른 부분을 모조리 추상화하여 개발자들이 브라우저에 관계없이 웹사이트에 단인 API를 사용할 수 있게 해주었다는 사실 때문이다.

그 후로는 애플리케이션과 유사하게 동작하는 웹사이트를 개발할 수 있도록 구현된 프레임워크들이 등장했다. 이들은 완전히 새로운 방식을 도입했다. 예를 들어, jQuery는 DOM을 조작하는 데 필요한 탁월한 도구들을 제공하지만, 애플리케이션 구조에 맞게 코드를 정리하는 것에 대한 실질적인 가이드라인을 제공하지는 않았다. 'jQuery 애플리케이션'을 구현한 코드가 오히려 유지보수가 어렵고 확장성이 떨어지는 괴상한 코드로 변하고 말았다는 안타까운 소식ㅇ르 듣게 되는 것은 바로 이점 때문이다.

이후 유지보수가 쉬운 대규모 자바스크립트 애플리케이션 개발에 대한 수요가 증가하면서 자바스크립트 프레임워크는 전성시대를 맞이한다. 최근 2~3년 사이에는 수많은 프레임워크가 등장하고 또 아무도 모르는 사이에 사려져 갔다. 그러나 몇몇 프레임워크는 유지보수가 쉽고 확장 및 테스트가 수월한 대규모 웹 애플리케이션을 개발하기 위한 필수 옵션으로 자리매김했다. 그중에서도 첫 손가락에 꼽히지는 않지만 매우 대중적으로 알려진 프레임워크가 바로 구글이 개발한 AngualrJS다.

그리고 '웹 엔지니어의 교과서'라는 책에서는 다음과 같이 말하고 있다.

jQuery로 프런트엔드 개발이 매우 편해졌다는 사실을 알았습니다. 그런데 왜 Backbone.js, AngualrJS, Ember.js, Vue.js와 같은 Javascript 프레임워크가 등장한 걸까요? jQuery만으로는 부족했을까요? 그 이유는 크게 두가지로 들 수 있습니다.

1) DOM 변경에 약한 jQuery

- DOM구조에 기반한 탐색으로 인해 DOM 구조변경에 오히려 취약함

- $("$target").parent().next().find(".default").hide();
- 리팩토링이나 수정, 디자인 변경 등으로 DOM구조가 바뀌어 지금까지 next()로 찾았던 형제 요소를 더는 찾지 못하는 상황 등은 충분히 예상할 수 있습니다. 그때마다 짜증을 내면서 jQuery를 수정한 경험이 많을 것으로 생각합니다.

2) 대규모화된 프런트 엔트 개발
- 서버사이드 개발에서 이전부터 MVC라는 디자인패턴을 이요하여 비즈니스 로직은 모델에, 디자인은 뷰에 책임을 분산했습니다. 최근 프런트 엔드 개발 규모가 커지나 서버사이드 개발과 마찬가지로 프런트 엔드 개발에서도 MVC 디자인 패턴으로 비즈니스 로직과 디자인을 따로 분리하려는 경향이 보입니다.

두 책에서 언급한 내용을 요약하자면, 브라우저 호환성을 보장하면서 DOM 조작에 탁월한 능력을 보여주는 jQuery는 DOM 탐색에 기반한 구조가 오히려 유지보수성을 떨어뜨리는 면이 있으며, 보다 큰 차이점은 간단한 웹페이지들의 모음이 아닌 응용프로그램으로써의 규모있는 SPA 환경일 경우 MVC 아키텍처가 가져다 주는 유지보수성과 테스트용이성, 확장성이란 점이다.

물론 AngularJS를 만나면 가장 먼저 눈에 띄는 장점인 '양방향 바인딩'도 jQuery에서는 제공되지 않는 기능이다.
(웹 페이지의 양방향 바인딩은 knockout.js를 첨 접했을 때 깜놀한 기억이 난다. => http://m.mkexdev.net/268)

결론적으로 다시 말하지만, 이 둘은 완전히 서로를 대체한다고 보기는 힘들다는 것이다.

두 프레임워크의 사상과 추구하는 목적이 다르다는 점, 그에 따라 쓰임새 역시 다를 수 밖에 없는것이다. 정말 고무적인 것은 이 둘을 같이 사용할 수 있다는 것이며, AngularJS는 내부적으로 jQuery를 포함하고 있다는 점이다. 이 점은 그야말로 더욱 훌륭하다 하겠다.

* AngularJS의 빠른 학습

앞서 소개한 책은 AngularJS를 실제 SPA 응용프로그램을 작성해 보면서 배울 수 있는 좋은 기회를 제공한다. 또한 AngularJS의 내부동작 등 심도있는 내용도 같이 포진되어 있어 많은 걸 배울 수 있다.

그리고 깊이는 좀 덜하지만 빠르게 테스트 해 볼 수 있는 학습도구로, w3cshools의 다음 강좌를 참조하면 좋다.

http://www.w3schools.com/angular/

마지막으로 AngularJS 자체에서 제공하는 api 문서는 늘 곁에 함께...

https://docs.angularjs.org/api

'모바일 > Javascript' 카테고리의 다른 글

[AngularJS] Two-way Data Binding  (0) 2016.07.10
[AngularJS] MVC Pattern in Angular  (0) 2016.07.10
knockout.js  (0) 2013.11.14
OOP in Javascript  (0) 2013.08.16
함수에 대하여  (5) 2013.07.31

knockout.js

Posted in 모바일/Javascript // Posted at 2013. 11. 14. 14:16

방안의 코끼리 마냥 본다본다 하던게 오래되어, 이제야 맘먹고 제대로 살펴 보게 되었다.

 

'넉아웃' 이라는 흥미로운 이름의 자바스크립트 라이브러리인데, 이놈 물건이네!

 

동적 웹 UI 구현의 생산성과 안정성이 매우 향상될 것으로 보인다.

점점 훌륭한 오픈소스 라이브러리들이 출현하고, 개발자는 점점 코어 구현에서 멀어지고...

 

빠르고 안정적이면서 유연성마저 좋은 스마트한 응용프로그램을 쉬이 개발할 수 있는 장점 이면에는, 소프트웨어 구조 설계와 코어 구현의 고민과 경험을 빌려 쓰게 되면서 궁극의 개발 스킬 향상을 저해하는 면이 있다 하겠다. 현 시대가 빠른 출시, 잦은 변경, 복잡한 비즈니스에 초점이 맞춰 지다 보니 이러한 라이브러리에 의존하는 것이 당연하게 받아 들여지지만 한편으로는 비즈니스가 아닌 소프트웨어의 코어 수준의 고민은 여전히 필요한게 아닌가 한다.

 

그럼... 잡설은 집어치우고.

 

knockout.js의 실행 흐름을 도식화 해봤다.

 

 

 

MVVM (모델, 뷰, 뷰모델) 패턴을 기반으로 뷰를 위한 뷰모델 계층이 존재하고, 이 뷰모델의 변경을 관찰하여 뷰와 자동 상호작용이 가능토록 구현된 라이브러리이다.

 

뷰모델 역할을 하는 객체를 knockout.js에 바인딩하면 knockout.js는 뷰모델 객체의 프러퍼티를 관찰/감시하게 된다. 만일 관찰 대상으로 지정된 뷰 모델 객체의 프로퍼티가 변경될 경우 연결된 HTML Element로 변경 내용이 전파된다. 또한 HTML Element에 연결된 프로퍼티는 HTML Element의 이벤트에 반응해 자동으로 값이 변경되기도 한다.

 

대부분의 예제에서 HTML Element의 이벤트에 기반해 뷰모델의 프로퍼티가 변경되는 것을 보여주지만, HTML Element에 의존없이 뷰 모델 프로퍼티만 변경되어도 자동으로 뷰가 갱신되도록 할 수 있어, 매우 참신하다.

 

간단한 예를 들어, 1초마다 시간을 갱신시켜 주는 코드를 다음과 같아 쉽게 구현할 수 있다.

데이터 변경에 따라 UI를 갱신하는 따위(?)의 코드는 존재하지 않는다.

<p>Time: <span data-bind="text: time" /></p>

 

 

   var viewModel = { time : ko.observable(new Date().toString()) };
   
   function onLoad(){             
       ko.applyBindings(viewModel);
       setInterval(clock,1000);
   }
   
   function clock(){
       viewModel.time(new Date().toString()); 
   }
  
   window.addEventListener('load', onLoad);

 

knockout.js 공식 사이트에 보면 주요 예제가 일목요연하게 정리되어 있어 적절한 활용처를 판단하는데 도움을 얻을 수 있다.

: http://knockoutjs.com/examples/

 

그리고 닷넷 기술과 함께 knockout.js를 활용하여  SPA(Single Page Application)를 구현한 좋은 사례를 다음의 MSDN 매거진에서 확인할 수 있다.

: http://msdn.microsoft.com/ko-kr/magazine/dn463786(en-us).aspx

 

 

'모바일 > Javascript' 카테고리의 다른 글

[AngularJS] MVC Pattern in Angular  (0) 2016.07.10
[AngularJS] 일주일 탐방기  (0) 2016.07.06
OOP in Javascript  (0) 2013.08.16
함수에 대하여  (5) 2013.07.31
null과 undefined 그리고 NaN  (0) 2013.07.29

OOP in Javascript

Posted in 모바일/Javascript // Posted at 2013. 8. 16. 14:34

 

   /* 클래스, 인스턴스/클래스 변수, 메서드 */
   function Person(name){      
      this.name = name;                              //인스턴스 멤버변수(public)
      var nickname = 'pretty_' + name;         //함수 지역변수(private)  
      this.getNickName = function(){            //메서드(지역변수 엑세스)
           return nickname;
      }
    } 
   
    Person.cName = "인간";                                     //클래스 멤버변수  
    Person.prototype.age = 39;                               //인스턴스 멤버변수 추가   
    Person.prototype.getSummary = function(){        //메서드 추가
        return this.name + '(' + this.getNickName() + ')';  
    }
  
   var person = new Person('박종명');        //인스턴스 생성
   console.log(person.name);                    //인스턴스 변수 액세스
   console.log(person.getNickName());       //메서드 엑세스(메서드를 통해 함수의 지역변수 액세스) 
   console.log(Person.cName);                  //클래스 변수 액세스  
   console.log(person.getSummary());   
  
  
   /* 상속  */
   function Korean(name,age){
       Person.call(this,name);          //부모 생성자 함수 호출
       this.age = age;
   }


   Korean.prototype = new Person();        //상속


   Korean.prototype.getSummary = function(){     //오버라이딩
     return this.name + '(' + this.getNickName() + ')' + '(' +  this.age + ')';  
    }
      
   var koreanPerson = new Korean('한국사람',20);     //자식 인스턴스 생성
   console.log(koreanPerson.name);                         //부모 멤버변수 엑세스
   console.log(koreanPerson.getSummary());             //자식 오버라이딩 메서드 엑세스
  
  
   /* 객체 타입 확인 */
   console.log(person instanceof Person);
   console.log(koreanPerson instanceof Person);

'모바일 > Javascript' 카테고리의 다른 글

[AngularJS] 일주일 탐방기  (0) 2016.07.06
knockout.js  (0) 2013.11.14
함수에 대하여  (5) 2013.07.31
null과 undefined 그리고 NaN  (0) 2013.07.29
스크립트 실행 지연  (0) 2013.07.23

함수에 대하여

Posted in 모바일/Javascript // Posted at 2013. 7. 31. 10:33

자바스크립트를 공부하다 보면 함수의 독특함에 많이 놀라곤 한다

이 언어가 가지는 유연함의 중심에 함수가 있으며 과히 함수기반 언어라 할 수 있다

 

먼저 모든 프로그래밍 언어에 존재하는 함수는 수학의 그것과 개념적으로 완전히 동일하다

즉 입력 값(x)에 대응하는 출력 값(y)이라는 개념 즉, f(x) = y라는 수학적 개념이 프로그래밍 언어에도 그대로 계승되었다는 것이다

 

 

 

먼저 가장 일반적인 함수 형태를 살펴 보자

//함수 정의
function Size(width,height){
    var size = width * height;
    return size;
}
       
//함수 호출
var size = Size(10,10);   
console.log(size); //100

 

function 이라는 키워드를 사용하여 함수를 정의할 수 있는데 위의 예에서는 너비와 높이를 입력 값으로 받아서 두 값의 곱 즉 사이즈를 출력(반환)하는 함수를 정의하고 호출하는 코드를 작성했다

 

return 문은 없어도 된다(이 경우 undefined가 반환된다)

대부분의 프로그래밍 언어처럼 자바스크립트 함수에서도 반드시 return으로 반환해야 하는 것은 아니다

대체로 void 함수로 정의하는데 자바스크립트에서는 반환 값의 타입을 지정하지 않기 때문에 다음 코드와 같이 return 반환이 없는 함수를 정의할 수 있다

 

function writeLog(message){
   console.log(message);
}

 

이 경우, 한가지 참고할 사항은 return 없는 함수의 호출 결과는 자동으로 undefined가 반환된다는 점이다.

return문을 통한 명시적 반환이 없는 함수가 자동으로 뱉는 undefined는 실제 프로그램에서 사용할 일은 거의 없다고 봐도 개념적으로는 기억해 두는 것이 좋다

//return문이 없는 함수 정의
function writeLog(message){
    console.log(message);
}
            
var returnValue = writeLog('Hello'); //Hello
console.log(returnValue);               //undefined

 

 

매개변수의 데이터 타입을 명시하지 않아도 된다.

심지어 매개변수의 개수가 달라도 된다

C#과 같은 언어에서는 타입 안정성을 위해 데이터 타입 제약을 강하게 둔다. 즉 사용하고자 하는 데이터의 타입이 사전에 정확히 명시되어야만 컴파일을 허용한다(C#의 var 선언도 결국 컴파일 시점에 타입이 결정된다)

 

반면, 자바스크립트는 타입 제약이 느슨한 언어이다. 앞서 코드들에서 봤겠지만 함수의 출력값은 물론 입력 매개변수에 대해서도 타입을 지정하지 않는다

 

또한 더욱 심오한(?) 것은 입력 매개변수의 개수도 개의치 않는다는 점이다. 앞서 작성했던 Size() 함수를 호출할 때 함수에 정의된 입력 매개변수 보다 더 많은 매개변수를 전달해 보자

function Size(width,height){
   var size = width * height;
   return size;
}

 

//더 많은 매개변수 전달
var size = Size(10,10,10);
console.log(size); //100

 

위 코드는 여전히 잘 동작하며 원하던 100이라는 결과를 내뱉는다.

자바스크립트에서는 함수에 정의된 것 보다 더 많은 매개변수가 전달될 경우 그것들은 무시하게 된다

 

그럼 더 적은 매개변수를 전달하면 어떻게 될까?

var size = Size(10);
console.log(size); //NaN

 

결과는 NaN이다. 오류가 아니라 정상적으로(?) 결과를 반환하는 것이다.

자바스크립트에서는 함수에 정의된 것 보다 더 적은 매개변수가 전달될 경우 나머지 값은 undefined로 할당된다.

 

즉 위의 예에서는 width = 10, height = undefined 가 되어 다음 식으로 계산된 결과를 반환한 것이다.

 

10 * undefined = NaN

 

NaN이 반환된 것은 undefined가 숫자 문맥에서는 NaN으로 평가되고 NaN과 숫자의 연산은 모두 NaN이기 때문이다

 

함수 리터럴

자바스크립트엣는 이름 없는 함수를 정의할 수 있다. 이를 함수 리터릴이라 한다. 앞서 Size 함수를 함수 리터럴로 정의하면 다음과 같다

var f = function(width,height){
       var size = width * height;
       return size;
}
            
var size = f(10,10);
console.log(size); //100

 

위의 코드를 보면 함수의 이름이 생략되었다. 여기소 var f 는 함수의 이름이 아니라 변수이며 함수 리터럴을 변수에 할당한 것이다.

 

함수 정의와 호출을 동시에

다음 코드와 같이 자바스크립트는 함수 정의와 호출을 동시에 할 수 있도록 지원한다. 아래 코드는 함수 리터럴을 선언하고 바로 호출했지만 이름을 가진 함수도 동일하게 작성할 수 있다

var result = (function(width,height){
       var size = width * height;
       return size;
})(10,10);
            
console.log(result); //100

 

 

데이터로써의 함수

앞서 함수 리터럴에서 본 것 처럼, 함수를 변수에 할당할 수 있다는 것은 함수 자체가 데이터로써의 역할을 할 수 있다는 예기가 된다.  이번 예에서는 두 개의 함수를 정의하고 이를 배열에 담아 배열로 함수를 호출하는 예를 살펴보자.

function Size(width,height){
      var size = width * height;
      return size;

   
function Sum(value1,value2){
      return value1 + value2;      
}   
  
var functionArray = new Array();
functionArray[0] = Size;
functionArray[1] = Sum;

  
for(var i = 0; i < functionArray.length; i++){
   console.log(functionArray[i](i,i));

 

위 코드는, 함수 자체를 배열로 담을 수 있다는 것으로 함수가 데이터로써의 역할을 한다는 것을 다시 한번 확인 가능하며 더불어 자바스크립트의 배열 유연성을 덤으로 눈치 챌 수 있게 하는 예이다.

 

데이터로써의 함수 특징을 볼 수 있는 마지막 예는 함수의 매개변수로 사용되는 경우이다.

function Size(width,height){
      var size = width * height;
      return size;

      
function DoubleSize(value1,value2,func){
   return func(value1,value2) * func(value1,value2);
}  
   
//함수의 매개변수로 또 다른 함수를 전달
var result = DoubleSize(10,10,Size);
console.log(result); //10000

 

C#과 같은 언어에서도 delegate라는 개념을 기반으로 한 함수(메서드)의 데이터화를 지원하지만 자바스크립트의 그것에 비하면 역사적으로 늦은 편에 속한다.

 

객체로써의 함수

C#과 Java와 같이 자바스크립트에서도 객체 기반의 프로그래밍이 가능하다.

언어적인 특징으로만 보면 자바스크립트는 생성자 함수와 프로토타입을 기반으로 한 객체 지향 프로그래밍을 지원하며 클로저를 이용한 private 멤버 구현하는 등 C#과 Java의 그것과는 다르다 할 수 있지만 상속/오버라이딩, 캡슐화와 같은 객체의 특징을 비롯해 객체에 기반한 구조적인 프로그래밍이 가능하기 때문에 객체 기반 장점을 누릴 수 있다.

 

자바스크립트에서는 클래스 생성 구문이 없다. 다만 생성자 함수를 통해 클래스와 같은 원형을 만들 수 있다

다음의 코드는 Rect라는 생성자 함수를 정의해서 객체로 사용되는 예를 보여준다.

 

이렇게 객체로 사용하는 함수를 메서드라고 부르며 메서드에는 this라는 키워드로 자신의 객체에 접근할 수 있게 된다. 내부적으로 보면 메서드는 그 메서드가 속해 있는 객체를 묵시적으로 전달받게 되는데 이 객체를 this로 접근할 수 있다는 것이다.

 

//생성자 함수 정의
function Rect(width, height){
    this.width = width;
    this.height = height;
    
    this.Size = function(){
      return this.width * this.height;
    }
}
     
//객체 생성 및 활용
var rect = new Rect(10,10);
var size = rect.Size();
   
console.log(size); //100

 

여기서 한가지 주의할 점은, 생성자 함수를 객체로 생성해서 호출(메서드 호출)하는 것이 아닌 일반 함수로 호출할 경우에는 함수 안의 this는 전역 객체를 가리키게 된다는 것이다. 다음의 예를 살펴 보자.

//생성자 함수 정의
function Rect(width){
    this.width = width;    //this는 메서드와 일반함수로 호출될 경우 대상이 달라진다
}
   
//객체(메서드)로 호출(Rect객체의 멤버 변수 width 값을 수정한다)
var rectObj = new Rect(10);
       
//일반 함수로 호출(전역 객체의 width 값을 수정한다)
var rectFun = Rect(20)
   
console.log(rectObj.width); //10          
console.log(width);            //20

 

 

 

'모바일 > Javascript' 카테고리의 다른 글

knockout.js  (0) 2013.11.14
OOP in Javascript  (0) 2013.08.16
null과 undefined 그리고 NaN  (0) 2013.07.29
스크립트 실행 지연  (0) 2013.07.23
Pie.js  (0) 2013.07.16

null과 undefined 그리고 NaN

Posted in 모바일/Javascript // Posted at 2013. 7. 29. 12:10

대부분의 프로그래밍 언어는 null 이라는 특별한 값을 지원한다.

 

ex> var temp = null;

 

이 값(null)의 의미는 '아무런 값도 나타내지 않는다'라는 의미이며 다음의 구문과는 구분된다.

 

ex> var temp;

 

즉, null 은 어떠한 유효한 값도 아니라는 의미이지 값 자체가 없다는 의미가 아니라는 말이다. 다시 말해 변수 temp에는 어떤 유효한 데이터를 담지 않을 뿐, null 값을 가진다는 의미이다. 따라서 선언만 하고 값을 할당하지 두 번재 예와는 구분되는 것이다.

 

자바스크립트는 값의 비유효성과 관련한 또 하나의 의미를 제공하는데 바로 undefined이다.

앞서 두 번째 예가 바로 undefined의 예가 되겠다. 즉 선언은 되었지만 값이 할당되지 않는 변수에 접근할 경우 undefined가 된다.

 

var temp;
console.log(temp); //선언은 되었으나 값이 할당되지 않은 변수: undefined
            
temp = null;
console.log(temp); //여전히 유효한 값은 없으나 null로 할당된 변수: null

 

결론적으로 null은 null이라는 값이 할당된 경우이지만, undefined의 경우 선언은 되었지만 아무런 값도 할당되지 않은 경우로 요약할 수 있다.

 

좀 더 나아가 객체 환경에서의 undefined를 살펴볼 필요가 있다.

선언은 되었지만 값이 할당되지 않은 변수에 접근할 경우 undefined라 했다. 이 개념은 객체환경에서도 동일한다. 즉 선언은 되었지만 값이 할당되지 않는 객체 프로퍼티 역시 undefined이다.

 

여기에 한가지 더 기억해야 할 것은, 객체 환경에서는 선언되지 않는 객체 프로퍼티도 undefined라는 점이다.

일반 변수의 경우 선언되지 않은 경우 오류(Exception)을 내뱉지만 객체 프로퍼티일 경우에는 오류가 아니라 undefined라는 점이다.

 

function TempObject(){
    this.i;       
}
   
var tempObject = new TempObject();
console.log(tempObject.i); //선언은 되었으나 값이 할당되지 않은 객체 프로퍼티: undefined
console.log(tempObject.j); //존재하지 않는 객체 프로퍼티 역시...: undefined

 

문맥에 따른 null, undefined 평가

자바스크립트는 유연한 자동 형변환이 지원되는 언어이다. 자동 형변환이란 어떤 데이터 타입이 숫자와 함께 사용될 경우 자동으로 (원래 숫자 타입이 아닌 경우에도) 자동으로 정해진 숫자로 변환되는 것이다.

여기서 숫자와 함께 사용된 경우라는 의미가 바로 프로그램 문맥상 숫자 문맥으로 평가된다는 것이다.

 

null과 undefined 역시 문맥에 따른 자동 형변환이 된다.

 

Boolean 문맥

null과 undefined는 실제로 다른 값이지만 참/거짓(Boolean)으로 평가되어야 하는 경우 모두 false로 형변환이 된다.

var temp;      
console.log(Boolean(temp)); //강제 형변환: false
   
if(!temp) //자동 현변환: undefined가 자동으로 false로 변환됨
{
   console.log('temp 변수가 false로 평가되었습니다');
}

 

숫자 문백

숫자 문맥에서는 두 값이 차이를 보이는데 null의 경우 0으로, undefined의 경우 NaN으로 변환된다.

var temp1 = null;
var temp2;    
console.log(Number(temp1)); //강제 형변환: 0
console.log(Number(temp2)); //강제 형변환: NaN
   
console.log(temp1 + 2); //자동형변환: 2
console.log(temp2 + 2); //자동형변환: NaN

 

실제로 자바스크립트 모듈을 개발할 경우, 이러한 문맥상 자동형변환의 특징을 이용하는 경우가 많다.

만일 어떤 객체에 정의된 함수의 존재여부를 식별한 후 해당 함수를 호출하고 싶을 경우 다음과 같이 작성할 수 있다.

function TempObject(){    
     this.doWork = function(){
       console.log('doWork...');
     }              
}
  
var temp = new TempObject();
if(temp.doWork){
     temp.doWork();  //조건식이 true이므로 호출됨
}
if(temp.doWork2){
    temp.doWork2(); //조건식이 false이므로 호출되지 않음
}

 

그리고 외부 모듈을 가져다 쓰는 복잡한 스크립트 환경에서 전역 네임스페이스의 충돌을 방지하기 위한 조건식으로 사용되기도 한다.

 

다음의 경우를 살펴보자. 동일한 이름의 객체를 생성하면 오류는 나지 않지만 뒤에 선언된 이름이 앞선 이름을 덮어쓰게 된다.

var someName = { i : 10 };     
console.log(someName.i);  //10
   
var someName = { i : 20 };
console.log(someName.i);  //20

 

문제는 만일 someName이라는 심벌이 외부 모듈에서 전역 네임스페이스로 이미 사용중일 경우 이름 중복은 예상치 못한 결과를 초래하기 때문에 다음과 같이 전역 네임스페이스에 동일한 심벌이 존재하는지 여부를 판단하는 것이 좋다.

var someName = { i : 10 };     
console.log(someName.i);  //10
    
if(!someName){      //만일 someName이라는 심벌이 정의되지 않았다면 새로 정의한다.   
   var someName = { i : 20 };    
}
   
console.log(someName.i); //10

 

물론 이름 충돌 방지는 도메인 네임과 같은 고유성이 보장된 이름 규칙을 사용하고 나아가 익명함수로 전역 네임스페이스를 전혀 어지럽히지 않도록 하는 기법이 존재하지만 여기서는 그 평가로 사용되는 undefined 특징을 살펴본 것이다.

 

참고로 null과 undefined의 문맥에 따른 자동 형변환 표를 정리한다.

 

 Boolean 문맥 

 숫자 문맥 

 문자열 문맥 

  null

 false 

 0 

 "null" 

  undefined

 false

 NaN

 "undefined"

 

 

 

'모바일 > Javascript' 카테고리의 다른 글

OOP in Javascript  (0) 2013.08.16
함수에 대하여  (5) 2013.07.31
스크립트 실행 지연  (0) 2013.07.23
Pie.js  (0) 2013.07.16
Zepto.js  (0) 2013.07.15

스크립트 실행 지연

Posted in 모바일/Javascript // Posted at 2013. 7. 23. 11:52

기본적으로 HTML 파서는 문서 파싱 도중에 자바스크립트를 만나면,

파싱 작업을 멈추고 자바스크립트를 다운로드하고 실행되기를 기다린다.

 

이는 덩치 큰 외부 스크립트를 문서로 삽입할 때 문서 로딩 시간의 지연을 초래하는데,

이를 해결하기 위한 메커니즘 중 하나가 deferasync 속성이다.

 

<script> 태그에 사용할 수 있는 속성으로 단어 그대로 defer은 지연, async는 비동기 특징을 지닌다.

 

보다 자세한 내용은 아래 블로그 글에서 확인할 수 있다.

 

=> script 태그의 async와 defer 속성

 

defer/async와 HTML 파서의 상호작용은 다음 포스트에서 시각적으로 확인 가능하다

=> http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/

 

그리고 이 두 속성의 브라우저 지원 여부는 다음 포스트에서 바로 확인 가능한데...

=> http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution/

 

문제는 이들 속성을 지원하는 브라우저 상황이 일관되지 않아 실제 적용을 위해서는 고민이 필요하다.

 

DOM과 밀접히 상호작용하고 스크립트간 유효범위에 대한 액세스 규칙을 포함하는 등 복잡한 스크립트 환경에서는 로딩과 실행 순서에 민감할 수 있으니 자~알 보고 적용해야 할 것이다.

 

'모바일 > Javascript' 카테고리의 다른 글

함수에 대하여  (5) 2013.07.31
null과 undefined 그리고 NaN  (0) 2013.07.29
Pie.js  (0) 2013.07.16
Zepto.js  (0) 2013.07.15
자바스크립트 상속  (0) 2013.07.12

Pie.js

Posted in 모바일/Javascript // Posted at 2013. 7. 16. 19:00

border-radius와 같은 CSS3의 새로운 효과를 IE에서도 적용되도록 해 주는 라이브러리이다.

IE6 ~ 9까지 지원되는데 다음의 CSS3 효과가 지원된다.

 

지원되는 CSS3 효과: border-radius, box-shadow, linear-gradient

 

조건부 주석을 통한 스크립트 참조  또는 htc behavior 방식 둘 중 하나를 선택해서 구현할 수 있는데, 
IE에서만 별도의 동작을 요구하기 때문에 가볍게 적용할 수 있을 듯 하다.

 

점진적 퇴보 전략 대신, IE 사용자들에게도 CSS3 경험을 선사해 주겠다면 이 라이브러리 적용을 고려해 볼 하다. 아쉬운건 좀 더 많은 CSS3 효과가 지원되지 않는다는 점이다.

 

=> http://css3pie.com/

 

 

 

 

 

'모바일 > Javascript' 카테고리의 다른 글

null과 undefined 그리고 NaN  (0) 2013.07.29
스크립트 실행 지연  (0) 2013.07.23
Zepto.js  (0) 2013.07.15
자바스크립트 상속  (0) 2013.07.12
ProcessingJS, 자바스크립트 Canvas 라이브러리  (0) 2013.07.12

Zepto.js

Posted in 모바일/Javascript // Posted at 2013. 7. 15. 17:11

모바일 환경에서 사용할 만한 경량의 자바스크립트 라이브러리를 찾았다

 

Zepto.js 라는 라이브러리로 jQuery의 문법 구조를 그대로 유지하면서 꼭 필요한 기능만 제공하여 크기를 최소화했다.

 

모바일 환경에서 jQuery를 사용하기엔 좀 무거운 감이 있을 경우 대체안으로 적합해 보인다.

또한 UI는 jQuery Mobile과 같은 템플릿에서 벗어나고 싶지만 swipe, taphold와 같은 터치 관련 이벤트는 사용하고 싶을 경우에도 접합하다 하겠다.

 

Zepto.js는 Core 모듈과 모바일 운영체제를 식별할 수 있는 Detect 모듈, 비동기 통신을 위한 Ajax 모듈, 에니메이션 효과를 위한 Effects 모듈, 터치 이벤트 지원을 위한 Touch 모듈 등으로 구성되어 있다.

 

=> http://zeptojs.com

 

 

'모바일 > Javascript' 카테고리의 다른 글

스크립트 실행 지연  (0) 2013.07.23
Pie.js  (0) 2013.07.16
자바스크립트 상속  (0) 2013.07.12
ProcessingJS, 자바스크립트 Canvas 라이브러리  (0) 2013.07.12
평점에서 별표 마킹  (0) 2012.11.16

자바스크립트 상속

Posted in 모바일/Javascript // Posted at 2013. 7. 12. 18:02

객체 지향 언어의 면모를 여실히 보여주는 자바스크립트 상속! 다형성!

좋구먼~ ㅎㅎㅎ


넌 너무 유연해~~


var Polygon = function(){

    var self = this;

    self.type = "Polygon";    

    self.commonDo = function(){

        console.log("commonDoing...");

    };

    self.draw = function(){

        console.log("draw " + self.type);

    };

};


var Square = function(){

  var self = this;

  self.type = "Square";

  self.draw = function(){                              //오버라이딩

      console.log("draw " + self.type); 

  };

  self.squareDoing = function(){

    console.log("squareleDoing...");  

  }

};

Square.prototype = new Polygon();         //상속



var Triangle = function(){

  var self = this;

  self.type = "Triangle";

  self.draw = function(){                              //오버라이딩         

      console.log("draw " + self.type);

  };

  self.triangleDoing = function(){

    console.log("triangleDoing...");  

  }

};

Triangle.prototype = new Polygon();       //상속


....


var obj1 = new Square();

obj1.commonDo();

obj1.draw();     

obj1.squareDoing();       

var obj2 = new Triangle();

obj2.commonDo();

obj2.draw();

obj2.triangleDoing();          

console.log(obj1 instanceof Polygon);

console.log(obj2 instanceof Polygon);



prototype.js를 이용하면 보다 가독성 높은 상속 코드를 구현할 수 있다. 아래 코드는 prototype.js를 사용해서 이전 코드와 동일한 클래스 및 상속 구조를 구현한다

var Polygon = Class.create({

    initialize: function(){

        this.type = "Polygon";

    },  

    commonDo : function(){

        console.log("commonDoing...");

    },

    draw : function(){

        console.log("draw " + this.type);

    }

});


var Square = Class.create(Polygon,{

  initialize: function(){

        this.type = "Square";

  },  

  draw : function(){               

      console.log("draw " + this.type); 

  },

  squareDoing : function(){

    console.log("squareleDoing...");  

  }

});



var Triangle = Class.create(Polygon,{

  initialize: function(){

        this.type = "Triangle";

  },

  draw : function(){               

      console.log("draw " + this.type); 

  },

  triangleDoing : function(){

    console.log("triangleDoing...");  

  }

});



'모바일 > Javascript' 카테고리의 다른 글

Pie.js  (0) 2013.07.16
Zepto.js  (0) 2013.07.15
ProcessingJS, 자바스크립트 Canvas 라이브러리  (0) 2013.07.12
평점에서 별표 마킹  (0) 2012.11.16
자주 쓰는 jQuery 기능 - 이벤트 편  (0) 2011.08.04