2014/12/27 16:58

Web Components(웹 컴포넌트)는 W3C에서 나왔다. 웹 도큐먼트의 표현을 위젯이나 컴포넌트로 빌딩하는 개념으로 핵심은 HTML 앨리먼트끼리 상호작용하고 인캡슐레이션되게 만드는 기술이다. 2013년2014년 Google I/O 에서 Web Components에 대해 바이들맨이 설명을 상세히 하고 있다. 또한 Web Components org 사이트가 존재하여 관련 정보를 얻을 수있다. 







Web Components 구성 요소 


    


  - Shadow DOM

    + DOM과 Style을 인캡슐레이션 해준다. 

    + 예전에는 iframe등을 통해 위의 효과를 얻었다. 

    + shadow dom 외부의 js는 접근이 안된다. 

    + shadow boundary의 style은 외부로 영향을 미치지 않는다. 

    + polyfill 이라고 브라우져가 지원하지않으면 기능을 지원할 수 있게 도와주는 스크립트 파일이라고 보면된다. 

       webcomponents.js 파일 같은 경우가 polyfill 파일이고 이것을 <script src="webcomponents.js"/> 하면 Shadow DOM에 대해 

       모든 브라우져에서 사용할 수 있다. 하지만 브라우져 버전은 확인해야 함. 


  - HTML Templates

    + <template id="name"> ... </template> 형태로 DOM에서 작용할 테그를 정의한다. 

    + <template> 태그에 있는 것은 DOM에 들어가지 않는다. 

    + 스크립트를 통해 DOM에 포함되는 구조이다. 

    + <template> 태그는 크롬과 몇개 브라우져만 지원하고 있다. 그러나 이것 역시 polyfill을 설치하면 모든 브라우져에서 수행가능함


  - Custom Elements

     + HTML에 새로운 태그를 정의하는 것이다. 마치 Angular의 Directive(지시자)와 유사하다. 

     + <element name="x-dowon"> ...</element> 으로 하면 <x-dowon> 태그를 사용할 수 있다. 

     + 앨러먼트의 lifecycle 콜백이 존재한다. 

     + 사용자 정의 앨러먼트를 만들기 위해 Shadow DOM, HTML Template 등이 필요한 것이다.

     + document에 register(<custom elements>)를 등록한다. 


  - HTML Imports 

     + <link rel="import" href="x-dowon.html"> 설정을 <head> 태그안에 둔다. 

     + 사용하려는 웹 컴포넌트의 확장자 .html을 import 타입으로 link 태그를 사용한다. 


    * 발표 자료 링크

    


    ** Web Components 스팩에 준수하여 개발된 Custom Element는 서로 조합하여 사용가능하다. 




Polymer와 Web Components


  - 구글이 웹 컴포넌트 스팩에 따라 구현한 것이 Polymer 이다. Web Components Org에서 제공하는 webcomponents.js는 웹컴포넌트 맛을 볼 수 있는 버전으로 본다면 Polymer는 본격적으로 서비스에서 사용할 수 있는 다듬어진 기술로 본다. 파이어폭스는 X-Tags

  - Web Components의 구성요소를 지원하기 위해 Polymer는 다음과 같은 스택을 가진다. 

    + Native는 브라우져

    + Web Components 스팩 및 실제 필요한 몇가지 기능이 포함된 polyfill로서 platform.js 파일이 존재

    + Polymer 만의 API가 있는 polymer.js 코어

    + 구글의 API를 웹 컴포넌트로 만들어 놓은 Elements (Core, Paper)들이 있고 이를 토대로 Application을 만들 수 있는 길을 닦아 놓았다. 

   

  - Polymer와 Web Components에 대한 요약 정리

    


  - Polymer에서는 어떻게 쓰는지 바이들맨의 설명을 들어보자. (2014년 구글 I/O)

    + <polymer-element name="hi-dowon"> .. </polymer-element> 태그를 통해 Custom Elements를 만든다. 

    + <template> 태그를 사용하고 탬플릿안에서 {{ }} 머스태쉬를 사용해 Data Binding을 한다. (AngularJS 디렉티브의 @ 과 유사)

    + 물론 트위터 부트스트랩같은 UI F/W의 사용도 가능하다.(22분)

    + http://customelements.io/ 이나 http://component.kitchen/ 같은 곳에서 컴포넌트를 찾고 Bower를 통해 설치해서 사용한다. 

    + 구글의 다양한 서비스 API를 Polymer 기반 Custom Element로 만들어 놓았다. 

     


  - Material Design을 구현한 Polymer의 Paper Element 사용방법 (2014년 구글 I/O)

    + 머터리얼 디자인으로 웹/모바일 화면을 구현하고 싶다면 참조하자. 

    + RWD(Responsive Web Design, 반응형 웹 디자인)는 구글에서 Web Starter Kit 강좌에서 잘 설명해 주고 있다. 

    + Polymer Designer를 가지고 화면을 작성할 수 있다. (23분)

    + 하이브리드 앱 (Cordova)를 통한 예도 보여줌 (29분)

    + Layout : core-* element

       Material : paper-* element

       Theming : core-style

       Transition : core-animated-page

      을 통해 일반적으로 모바일에서 원하는 효과를 바로 얻을 수 있다. 

    + 그외 매튜 맥널티의 2014년 구글 I/O 마지막 동영상도 보자 

    


  폴리머의 장점은 재사용성에 있다고 본다. 디자이너와 같은 툴을 통해 미리 정의한 컴포넌트를 비즈니스에 맞게 가지고 있다면 사용자의 레벨에 따라 원하는 모바일/웹 환경을 쉽게 만들 수 있을 것이다. 따라서 반복적인 코드가 줄어 들 것이고 일관성있는 유지보수와 확장성을 보장할 것이다. 2년전 MEAN Stack을 통해 만들고 싶었던 것은 시각화 대시보드 저작도구 였다. HTML의 태그가 Custom Element처럼 표현이 되고 저작도구(Poly Designer)나 실시간에 해석되어 데이터를 실시간 차트로 보여줄 수 있는 BtoB 솔루션을 만들 수 있을 것이다. 이미 Flex 버전의 대시보드 저작도구를 개발해 보았지만 이제는 모바일/웹이 원활히 지원되는 기술로 바뀌어야 하기 때문에 Web Components는 나에게 더욱 필요한 머스트 아이템이 되겠다.  




<참조> 


  - 2013년 구글 I/O - Web Components Tectonic Shift

  - W3C의 Web Components Spec

  - Polyfill 개념

  - 2014년 구글 I/O - Web Components & Polymer (바이들맨의 Custom Element 정리)

  - Vanilla, X-Tags, Polymer 비교

  - Vulcanize : import 웹 컴포넌트 합쳐주는 도구

저작자 표시 비영리 변경 금지

'Web Components > Concept' 카테고리의 다른 글

[Web Components] 웹 컴포넌트 개념잡기  (0) 2014/12/27
Posted by peter yun 윤영식
2014/12/26 11:48

새 술은 새 푸데에 넣어 보자. 모던 웹브라우져기반하에 구조적인 웹 애플리케이션을 개발할 수 있도록 해주는 Dart로 구글의 Web Component스펙 구현체인 Polymer를 시작하는 것도 재미 있을 것이다. Dart기반으로 개발을 하게 되면 Dart VM이 설치된 브라우져에서 수행이 되어야 하지만 현재는 Chromium + Dart VM을 결합한 Dartium에서만 수행이 되고 Dartium 은 별도로 설치해도 되지만 DartEditor를 설치하게 되면 포함되어 있어서 통합 개발환경하에서 디버깅 및 수행을 해볼 수 있다. 하지만 dart2js 도구를 통해 .dart 파일을 .js파일을 transpile할 수 있어 기존 모던 웹 브라우져에서 수행이 가능하다. 



 



Chrome Dev Editor 설치


  - 구글 I/O에서 소개한 크롬 개발 에디터는 다트와 웹컴포넌트로 만들어진 크롬앱이다. 설치를 한다.

  - 깃헙 사이트에서 Chrome Dev Editor를 볼 수 있다. 하기 내용은 Chrome App 으로 프로젝트를 생성한 경우이다. Dart 기반으로 생성이 되었다. 

    


  - 개발도구를 통해서 웹 컴포넌트를 추가하면서 개발도구를 업그레이드하는 과정을 보자. 흥미롭다. 

    


  - 현재는 개발자 프리뷰버전이 나와있어서 열심히 개밥(dogfood)을 먹으며 실험을 하고 있는 단계이다. 하지만 1년 2년이 지나면서 성능과 안정성 대중성이 확보되리라 생각한다. 물론 극히 개인적인 추론이지만 구글의 문화를 토대로 본다면 2013년부터 구글 I/O에서 계속 Angular, Polymer의 소개가 빠지지 않고 전략적으로 밀고 있다는 생각이 든다. 





Polymer 개념 잡기 


  - Web Component는 div soup에서 벗어나 사람이나 기계가 인지할 수 있는 의미있는 단어로 HTML을작성하고 이를 컴포넌트화 하는 것이다. 

    + 의미있는 단어로 HTML을 작성하기 위해 div 태그를 재정의 할 수 있어야 한다. 

       이는 Template을 통해 Custom Elements를 만든다

    + 컴포넌트화 하기위해서는 상태에 대한 것과 동작에 대한 것에 scope를 줄 수 있어야 한다. 

       상태 scope는 CSS를 Shadow DOM이라는 기념하게 Custom Element의 Template에만 적용되는 CSS를 작성할 수 있다. 

       동작 scope는 자바스크립트로 작성을 할 수 있고 Polymer를 사용하게 되면 Dart를 통해서도 가능하다. 

  - Web Components는 Angular의 Directive 지시자와 유사하지만 약간의 차이가 존재한다. UI와 스크립트 언어간의 two-way data binding하는 reactive programming은 동일하지만 그외의 부분은 지향하는 바가 틀리고 할 수 있는 영역이 틀리다. Polymer는 좀 더 강력한 웹 애플리케이션 UI를 빨리 만들 수 있도록 지원한다. 

    


  - 내가 좋아하는 애디 오스마니의 Polymer 소개 영상을 보자. 무려 한글로 해석되어 나온다. 

    





Polymer와 Dart의 관계


  - Dart는 구조적 웹 프로그래밍 언어로 구글에서 만들었다. 동적 타입 언어에 조금이라도 익숙하고 자바를 다루어 본 개발자라면 쉽게 배울 수 있는 언어이다. DartEditor는 Eclipse기반이고 import, inheritance, main() 등 자바에서 볼 수있는 것들을 잘 차용했다. 하지만 다트는 Strong static type 시스템인 자바와 틀리게 Strong dynamic type 시스템을 지향하고 Optional static type 적용이 가능하다. Web Component 스펙의 구현체인 Polymer와 Dart의 공통점은 모던 웹 브라우져에 돌아가는 애플리케이션을 빠르고 견고하게 만들 수 있도록 하는것을 지향한다는 것이다. Dart는 dart2js 도구를 제공하기 때문에 .dart를 .js로 변환하여 Dart VM이 설치되지 않은 브라우져에서 실행이 가능한 것이다. 따라서 Polymer에 Dart를 안해 볼 이유는 없어 보인다. 

  - Dartlang.org의 Polymer 페이지의 첫 문구이다. 위에서 이야기한 내용을 축약해서 표현해 놓았다. 

Use polymer.dart—a Dart port of Polymer—to build structured, encapsulated, client-side web apps with Dart and web components.


  - 구조

    + web 폴더가 있고 그안에 html 파일이 존재

    + pubspec.yaml은 Dart의 의존관계 및 메타정보에 대한 공식 설정 파일이다. 

      이것은 Node.js의 package.json이나 Bower의 bower.json과 동일하다. 

      


  - 의존관계로 polymer.dart를 설치한다. pubspec.yaml 설정 내역이다. 

dependencies:

  polymer: ">=0.15.1 <0.16.0"

transformers:

- polymer


  - Dart 기반으로 Polymer를 팔려면 우선 다음과 같이 진행하는 것이 맞다. 

    + 우선 Dart 개념을 잡아야 한다. 

    + 다음에 자바스크립트 기반으로 Polymer를 해본다. 

    + 마지막으로 다트 기반으로 Polymer를 접근한다. 

  - Polymer.dart와 AngularDart의 관계는 Polymer와 AngularJS의 관계와 유사하다. 서로 자바스크립트이냐 다트이냐의 차이일 뿐 상호 겹치는 부분의 Data Binding에서 상호 작용(Interoperation)할 수 있다. 


  만약 모던 웹 브라우져라는 제약이 존재 한다면 언어의 구분을 두지 말고 내가 원하는 웹 애플리케이션을 빠르고 견고하고 구조적으로 만들 수 있는지 고려해 시작하자. 감기로 인해 오늘은 여기까지... 




<참조>


  - 구글 I/O Polymer 소개 영상

  - Dartium 소개

  - Angluar와 Polymer 사이의 Data Binding

  - Reactive Programming Wikipedia

저작자 표시 비영리 변경 금지

'Web Components > Polymer' 카테고리의 다른 글

[Polymer] Dart로 시작하는 폴리머  (0) 2014/12/26
Posted by peter yun 윤영식
2014/12/24 17:15

처음으로 새로운 프레임워크를 접하게 되었을 때 어떻게 시작해야할지 막막하다. 그럴땐 공부할 꺼리들을 정리해 보고 시작하자. 새롭게 시작할 AngularDart의 컨텐츠를 정리해 보자. 






처음 시작하기 


  - 처음은 무조건 사이트부터 방법해서 https://angulardart.org/ 

    + 다트 소개 영상이다. 모든 것이 잘 요약되어 있다. (시리즈 동영상들)

    


    + Angular의 철학에 근거해서 만들어 졌기 때문에 테스트 가능하고 간결한 웹개발을 이끈다.

    + Dart 언어를 사용하기 때문에 class, annotation, inheritance등은 자바 개발자에게 익숙함을 제공하고 확장가능한 웹을 만듦

    + 모던 웹을 위한 Shadow DOM, Web Component를 시작할 수 있다. 

    참조)  테스트 가능성은 Angular의 DI (Dependency Injection)을 통해 가능해 진다. 

             Two-way data binding을 통해 간결한 코드 개발이 가능하다.

  - Dart로 시작하는 AngularDart는 Web Component 스팩을 구현하고 있는 Polymer.dart와 함께 어떤 방향으로 가는지 먼저 본다. 

    + 본영상이 JavaZone에서 발표됐다는 것은 자바개발자에게 아주 익숙한 신택스로 Dart 언어가 구성되었기 때문일 것이다. 

    


  - Dart 언어에 대해 개념을 잡자

    + https://www.dartlang.org

  - DartEditor를 사용한다. 

    + 이클립스 기반이어서 자바개발자에게 친근감 마저 든다. 

    + 패키지 import 와 이클립스 debugging 등 확장자가 .java 에서 .dart로 바뀌고 웹과 서버 모두를 개발 할 수 있다. 

    


  - 코드랩을 따라한다.

    + 예제 데모를 돌려보면 최신 IE 11, FF, Safari, Chrome에서 잘 돌아감. 

    + HTML의 디렉티브는 AngularJS와 거의 같음. 코드만 .dart 로 작성함 

  - 개발하며 API를 참조한다.




AngularJS 개발자가 AngularDart 개발하기 


  - AngularDart의 상당 부분이 실은 AngularJS v2.0에 많은 영향을 미쳤다. (미스코의 말)

    + AngularJS개발자를 위한 AngularDart 이해하기

  - Dartlang을 모르고서 AngularDart를 보면 안되겠죠?  

  - UI Framework과 연동해서 웹 애플리케이션을 만들어 본다. (깃헙 소스)

    




AngularDart와 Polymer 연동하기


  - 우선 AngularDart 소개영상과 25분부터 이어지는 Polymer.Dart를 보자 

    + 보고 있으면 아마도 ng-conf 2014에서 소개한 Angular v2.0 영상의 14분 부터 보면 뭔가 떠오를지 모르겠다. 

    

 

  - 첫번째 영상에서 Web Component 개념을 이야기하는 Polymer.dart를 다시 보자. 

  - 다시 정리하고 있는 Parsley의 Web Component & Dart 동영상을 보자

  - 따라하기 하며 Dart와 Polymer.dart를 연결해 보기 


계속해서 업데이트 예정...




<참조> 


  - Dart와 Web Component에 대한 다른 영상

  - 미스코 헤베리의 AngularDart를 만든 이유 

The Angular team's mission is to make building web-applications easy on the web. We want to support as many languages as possible.

AngularJS supports: JavaScript and through transpilation CoffeeScript and TypeScript.

AngularDart obviously supports Dart. 

1) Dart is significantly different from JavaScript that transpilation approach would not create the experience we were looking for, for this reason we have rewritten it. 

2) Dart has Types, and Type annotations, and so while rewriting AngularDart we have chose to take advantage of these language features. 

3) We have also learned from our mistakes on AngularJS and taken the opportunity to correct them, such as much improved Directive API. Finally we have take advantage of the latest browser technologies and based AngularDart on top of Shadow DOM.

4) All of the learnings we have gained in building AngularDart, will be applied back to AngularJS v2. This is only expected since AngularDart is younger than AngularJS.

Angular is a philosophy on how applications should be built and we wanted to make the question of language choice orthogonal to your choice of using Angular. Any web-language you choose, there is an Angular you can use with it.



저작자 표시 비영리 변경 금지

'AngularDart > Concept' 카테고리의 다른 글

[AngularDart] 앵귤러다트 배우는 방법  (0) 2014/12/24
[Dart] 다트 언어 개념잡기  (0) 2014/12/24
Posted by peter yun 윤영식
2014/12/24 14:53

빠르게 메타지식을 흡수해 변환에 적응하는 능력을 지적 겸손이라 한다. 태도의 겸손이 아닌 내가 아는 것이 전부가 아니고 더 낳은 방법과 기술이 있다면 메타지식을 빠르게 흠수할 수 있는 능력이 필요한 시대가 되었다. 새로운 웹 개발언어로 성능과 생산성 증대를 목표로 하는 Dart에 대해 공부를 해본다.






중요 개념 


  - 모든 변수는 Object 이다. 

  - 정적 타입과 동적(dynamic) 타입이 가능하다   

  - 정적 타입 오류를 컴파일 타임에 알려준다

  - main() 펑션이 있다

  - public, protected, private 같은 것이 없고 _ (underscore)로 표현한다 

  - warning 은 프로그램이 수행 안될지도 모른다 이지만 수행을 막지는 않는다. 

    error가 컴파일 타임이 나면 수행할 수 없고 런타임에 발생하면 exception이 발생한다.  

  - 런타임 모드는 production 과 checked 두가지다. 개발시에는 checked 모드로 사용한다. 

     production 모드에서는 assert 구문을 무시한 최적화를 통해 성능을 향상시켜준다. 

  - 키워드 

   

    1 : built-in indentifier : 자바스크립트를 다트로 포팅을 쉽게 해준다. 

    2 : 제한적인 예약어로 비동기 지원과 관련이 있다. 

    



변수 (Variables)


  - 예 : 'Peter' 값을 가지는 String 객체의 레퍼런스 주소값을 name이라는 변수가 가지고 있다. 

var name = 'Peter';


  - 최기화 되지 않은 변수는 null 초기값을 갖는다. 숫자가 초기값이 없어도 null 초기값을 갖는다. 

    assert 구문은 production 모드에서 무시된다. 만일 assert 구문이 true가 아니면 exception을 던진다. 

int lineCount;

assert(lineCount == null);


  - 옵셔널 타입으로 String name = 'Bob'으로 직접 지정해 줄 수도 있지만 타입 스타일 가이드에 따라 var를 사용한다. swift와 유사함 

  - final은 변수의 값을 변경하고 싶지 않을 경우 var 대신 사용한다. const는 수치값을 지정한다. 

  - numbers, strings, booleans, lists, maps, symbols 관련 빌트인 타입을 가지고 있다. (예제 참조)

    + numbers : int, double 있고 이들은 num의 서브타입이다. 다트의 int와 자바스크립트 int는 틀리다. 다트 int는 arbitrary-precision integer

    + strings : UTF-16 코드를 따르고 ''  또는 "" 사용가능. 'hi peter ${expression}' 식으로 문자안에 ${} 표현가능. swift와 유사함

    + booleans : bool 타입으로 true, false를 값을 가져야 하고 자바스크립트와 틀리다. 즉, var name='pter'; if(name)하면 false이다. 

    + lists : 다트의 배열은 List 오브젝트이다. 인덱싱은 0부터 시작한다. GenericsCollections을 살펴보자 

    + maps : key-value에 대해 Map 오브젝트를 사용한다. JSON처럼 literal 지정 

    + symbols : Symbol 오브젝트를 통해서 operator와 identifier를 표현한다. 




펑션 (Functions)


  - 예 : 스타일 가이드에 따라 파라미터와 리턴 타입 지정한다. 

// 파라미터와 리턴 타입을 명시하는게 스타일 가이드 

void printNumber(num number) { 

  print('this is $number');


// 하지만 생략도 가능 

printNumber(number) 

  print('this is $number');

 


  - => expr;{ return expr; } 표현과 같다. coffeescript 같은 축약형 좋다. 하기 표현은 위 표현과 동치 

printNumber(number) => print('this is $number');


  - 옵션널 파라미터

    + 기본 설정 : enable(bool flag1, bool flag2) { ... }

    + Optional named parameter는 paramName: value로 지정 

       예) enable({bool flag1: false, bool flag2: true}) { ... } 사용 enable(flag1: true)

    + Optional positional parameter는 [] 마크를 사용

       예) say(String from, String msg, [String device]) { ... } 사용 say('hi', 'peter') 또는 say('hi', 'peter', 'ios')

  

  - 애플리케이션은 최상위 레벨에서 main() 펑션를 갖는다. 애플리케이션의 진입점역할을 한다. 자바와 유사함

    .. 오퍼레이터는 cascade operator이다. 즉, 이어서 호출한다. 

void main() {

  querySelector('#peter')

    ..text = 'Hi dowon'

    ..onClick.listen(reservedText);


  - Functions as first-class objects 이다. 펑션을 다른 펑션에 파라미터로 전달하거나 리턴하는 것이 가능. 이건 자바스크립트부터 쭉... 

printElm(element) {

  print(element);

}


var list = [1,2,3];

list.forEach(printElm); // printElm을 파라미터로 전달 


  - 자바스크립트는 function 레벨에서 lexical scope를 갖듯 다트도 lexical scope를 갖는다. 즉, 변수의 스코프가 정적으로 정해진다. (단, 자바스크립의 this는 호출되는 시점에 결정되므로 이부분에 틀림. 아래 참조 링크를 보자) 다트는 curly raches outwards를 따른다. (자바스크립트는 변수에 var를 줌으로 로컬 변수 스코프임을 지정한다) 

  - lexical closures는 lexical scope안의 변수를 접근하는 펑션 오브젝트이다. 

closure is a function object that has access to variables in its lexical scope, even when the function is used outside of its original scope.


  - 모든 펑션은 리턴값을 갖고 지정하지 않으면 return null; 이다. 




연산자 (Operators)


  - 연산자 종류 

    


  - 타입 테스트 오퍼레이터 

    



제어 흐름 (Control Flow Statement)


  - if(){ ... } else if() { ... } else { ... }

  - for ( 초기값 ; 비교 ; 증분 ) { ... } 또는 for in 

  - while() { ... } 또는 do { ... } while ()

  - while에서 break, for 에서 continue 

  - switch ~ case ~ default




예외처리 (Exceptions)


  - 다트의 예외는 unchecked exception 이다. 

  - 다트는 ExceptionError 타입을 제공한다. 

  - throw 하면 에러를 일으킨다. 

  - on catch 으로 exception을 catch 하고 전파되는 것을 막는다. 

try {

  aa();

} on OutofException {  // known exception

  bb();

} on Exception catch (e) { // anyting else that is an exception

  print('exception is: $e');

} catch (e) {

  print('really unknown : $e');

}

 

  - finally : finally가 수행된 후에 exception이 전파된다 




클래스 (Classes)


  - 다트는 객체지향 언어이다. 

  - new 키워드로 클래스의 인스턴스인 오브젝트를 생성한다. 

  - 클래스는 펑션과 데이터를 멤버로 갖고 특히 오브젝트의 펑션을 메소드라 부른다. dot(.)로 호출한다. cascade operator(..)은 싱글 객체의 멤버를 연속적으로 호출할 때 사용한다.

  - 생성자는 클래스와 같은 이름을 자고 this는 현재 인스턴스를 가르킨다. 자바와 유사

  - 생성자를 선언하지 않으면 아규먼트 없는 기본 생성자가 자동 제공됨. 자바와 유사 

  - 생성자는 상속되지 않는다. 

class Point {

  num x;

  num y;


  Point(this.x, this.y);

}


  - get, set 키워드를 통해 프로퍼티를 만들 수 있다. 

class Rectangle {

  num left;

  num top;


  Rectangle(this.left, this.top);


  num get right   => left;

         set right(num value) => left = value - left;

}


  - abstract class를 만들 수 있다. 상속은 extends를 사용함.  자바와 유사 

abstract class Door { 

  void open();

}


  - 연산자도 오버라이드 할 수 있음 

  - 모든 클래스인 암묵적으로 interface를 정의할 수 있다. 만일 A 클래스가 B의 구현체를 상속받지 않고 B의 API만을 사용하고 싶을 경우 implements 키워드를 사용한다. 자바에는 없는 재미난 부분

// A person. The implicit interface contains greet().

class Person {

  final _name;          // In the interface, but visible only in this library,

  Person(this._name);   // Not in the interface, since this is a constructor.

  String greet(who) => 'Hello, $who. I am $_name.'; // In the interface.

}


// An implementation of the Person interface.

class Imposter implements Person {

  final _name = "";      // We have to define this, but we don't use it.

  String greet(who) => 'Hi $who. Do you know who I am?';

}


greetBob(Person person) => person.greet('bob');


main() {

  print(greetBob(new Person('kathy')));

  print(greetBob(new Imposter()));

}


  - extends 키워드로 상속을 하고 super는 부모 클래스를 가르킴. 자바와 유사

  - 상속시 부모 메소드에 대한 @override를 명시적으로 사용해 오버라이딩이 가능하다. 

  - 클래스에 @proxy라고 하면 @override시에 warning을 준다. 

  - 다중 상속시에 mixin 개념의 클래스 코드 재사용이 도입. with 키워드를 사용한다. mixin 할때는 upser, 생성 선언이 없다. 

class Musicain extends Performer with Musical, Aggressive, Demented { 

  ...

}


  - 클래스 소속 메소드와 변수는 static 키워드를 사용한다. 자바와 유사




제네릭 (Generics)


  - 다트에서 타입은 옵셔널이다. 의도를 명확히 하기 위해 공식적으 타입 파라미터를 같는 타입이다. (generic == parameterized) type

    예에서 문자로 지정을 한다는 의도를 분명히 한다. 

var names = new List<String>();

names.addAll(['Seth', 'Kathy', 'Lars']);

// ...

names.add(42); // Fails in checked mode (succeeds in production mode).


  - type variables로는 통상 E, T, S, K, V 같은 단일 문자를 갖는다. 

  - 제네릭은 코드의 중복을 방지해 준다. 상속하여 구현 하면 됨 

// Object 경우 

abstract class ObjectCache {

  Object getByKey(String key);

  setByKey(String key, Object value);

}


// String 경우 

abstract class StringCache {

  String getByKey(String key);

  setByKey(String key, String value);

}


// 하나로 줄여줌 

abstract class Cache<T> {

  T getByKey(String key);

  setByKey(String key, T value);

}


  - Collection literal에도 사용가능하다. 

var names = <String>['Seth', 'Kathy', 'Lars'];

var pages = <String, String>{

  'index.html': 'Homepage',

  'robots.txt': 'Hints for web robots',

  'humans.txt': 'We are people, not machines'

};


 


라이브러리와 가시성 (Libraries and visibility) 


  - import, part, library 지시자(Directives) 사용한다. 

  - 라이브러리는 Pub Package and Asset Manager인 pub 툴로 패키지를 사용 배포한다. 

  - import 'dart:html';  형식으로 import는 URI 형시그로 라이브러리를 지정한다. 

  - 빌트인은 'dart:xxx' 로 시작한다. 

  - pub 툴 배포로 제공되는 것은 import 'package:<file path>'; 로 지정한다. 예) import 'package:utils/utils.dart';

  - as로 aliasing이 가능 예) import 'package:lib2/lib2.dart' as lib2; 

  - show, hide 통해 라이브러리 일부만 가져오기 가능 예) import 'package:lib2/lib2.dart' show foo;

  - 라이브러리의 Lazily loading이 가능하다. deferred as 키워드를 사용한다. AngularJS의 $q를 보자  

    + 애플리케이션 초기 시작시간을 줄이기 위해 사용

    + A/B 테스트를 수행하기 위해

    + 사용이 적은 것들 로딩할 때 

    예) import 'package:deferred/hello.dart' deferred as hello;  하기에 then 구문으로 비동기적 호출을 한다.

hello.loadLibrary().then((_) {

  hello.printGreeting();

});


  - 다른 방법으로는 async 키워드를 사용한다. loadLibrary()는 Future를 리턴한다. 

greet() async {

  await hello.loadLibrary();

  hello.printGreeting();

}


  - library <라이브러리명칭>; 으로 사용한다. part는 라이브러리의 첨부된 파일을 지칭한다. 

library ballgame;   // Declare that this is a library named ballgame.


import 'dart:html'; // This app uses the HTML library.


part 'ball.dart';  // ballgame의 일부이다. 


 


비동기 지원 (Asynchrony support)


  - async 와 await 키워드를 사용한다. 

  - 다트 라이브러리는 Future 오브젝트를 리턴하는 펑션셋을 가지고 있다.  

  - dart 또는 dartanalyzer에서 async 지원을 위해 옵션을 주어야 한다. DartEditor (Eclipse기반)에도 넣어줌 

    

dart --enable-async async_await.dart

dartanalyzer --enable-async async_await.dart


  - async 펑션선언 

check() async {

  //...

}


look() async => //...


  - await <expression> 에서 expression은 타입 Future를 가지고 있고 이는 오브젝트를 리턴하기 위한 promise이다. 리턴된 오브젝트가 유효할 때까지 실행은 멈춘다. 




Typedefs


  - 다트에서 펑션, 문자, 숫자 모두 오브젝이다. 

  - typedef 또는 function-type alias 는 필드나 리턴타입을 선언할 때 사용할 수 있는 펑션타입에 이름을 준다. 

// f를 compare로 할당할 때 int f(Object, Object)의 타입정보가 사라진다.

class SortedCollection {

  Function compare;


  SortedCollection(int f(Object a, Object b)) {

    compare = f;

  }

}


// typedef로 펑션타입을 정의한다.

typedef int Compare(Object a, Object b);


class SortedCollection {

  Compare compare;


  SortedCollection(this.compare);

}




메타데이터 (Metadata)


  -  메타데이터는 추가적인 정보를 주기위해 사용한다. @ 키워드로 애노테이션을 사용한다. 

  - @deprecated, @override, @proxy 등의 메타데이터 애노테이션을 사용한다. 

  - 커멘트는 한줄 // 사용하고 다중은 /* */을 사용한다. 




참조 

  

  - 다트 기초 

  - 구글 취업이 원하는 인재상 : 지적 겸손에 대하여

  - 자바스트립트에서의 lexical scope와 this의 의미 번역 (원문)

  - 컴퓨터 사이언스에서 Lexical Scope 위키피디아

  - Dart Slides 및 동영상

  - Dart VM으로 서버 만들기 Framework 종류

저작자 표시 비영리 변경 금지

'AngularDart > Concept' 카테고리의 다른 글

[AngularDart] 앵귤러다트 배우는 방법  (0) 2014/12/24
[Dart] 다트 언어 개념잡기  (0) 2014/12/24
Posted by peter yun 윤영식
2014/12/15 19:43

배너 밑으로는 선전하고 싶은 상품 목록 4개를 열거한다. 이때 반응형 웹 디자인의 그리드(Grid)를 적용해 본다. 




화면 분할


  - WEB-INF/templates/layout/home.html 템플릿의 내용이 많아지면 partial html로 분리하여 include하는 방식을 취한다

  - 우선, Homepage Banner Ad Carousel 부분을 <th:include> 처리하고 Product 목록 부분도 <th:include> 처리해 관리한다. 

  - 기존 화면 

   


  - 변경 화면

    + 박스 테두리 CSS를 적용한다

    + 각 박스 테두리별로 반응형 그리드를 적용한다  

   

  - WEB-INF/templates/layout/home.html 내역중 Carousel에 대한 부분과 product 목록에 대한 부분을 WEB-INF/templates 폴더 밑에 main/partials 폴더를 새롭게 만들고 banner-caruosel.html 과 product-list.html 을 생성하고 기존 내역을 옮긴다. 

  - content의 contentType인 "Homepage Featured Products Title" 인 목록을 뿌려주는 것이다. 

  - layout 폴더에서 main 폴더로 옮기는 이유는 해당 main 폴더 영역에 있는 부분이 계속 변경되기 때문이다. 즉, 다른 페이지로 이동해도 nav와 footer는 고정되어 있다. 

// home.html의 과거 내역 


<blc:content contentType="Homepage Featured Products Title" />    

<div th:if="${contentItem !=null and contentItem['messageText'] !=null}" class="title_bar" th:text="${contentItem['messageText']}"></div>


<ul id="products" class="group">

    <li th:each="product : ${products}" th:object="${product}" th:include="catalog/partials/productListItem" class="product_container"></li>

</ul>



// 신규 layout/home.html 일부 내역 


    <div th:include="main/partials/banner-carousel" />

    

    <div class="section">

        <div th:include="main/partials/featured-products" />

    </div>



// main/partials/featured-products.html


    <div class="container">

   

          <div class="row">

          <blc:content contentType="Homepage Featured Products Title" />  

             <div th:if="${contentItem !=null and contentItem['messageText'] !=null}" 

                  class="col-lg-12 col-md-12 col-sm-12 col-xs-12 featured-title" 

                  th:text="${contentItem['messageText']}"></div>

       

              <div th:each="product : ${products}" 

                   th:object="${product}" 

                   th:include="catalog/partials/productListItem" 

                   class="col-lg-3 col-md-3 col-sm-6 col-xs-6">

              </div>

          </div>

          

    </div>


  - class="col-lg-3 col-md-3 col-sm-6 col-xs-6" 을 적용해서 데스크톱에서는 4개씩 상품이 보이고 테블릿 이하는 2개씩 상품이 보임




Product Item 그리드 구성 


  - th:include="catalog/partials/productListItem" 에서 기존 productListItem.html 의 CSS를 하기와 같이 다시 적용한다 

    + max-width: 320px; 를 주어 박스의 최대 크기를 지정한다. 

// /webapp/css/style.css 일부 내역 


/************************************/

/* featured product list  */

/************************************/

.thumbnail {

max-width: 320px;

display: block;

padding: 5px;

margin-bottom: 10px;

line-height: 1.5;

background-color: #fff;

border: 1px solid #ddd;

border-radius: 4px;

-webkit-transition: border .2s ease-in-out;

-o-transition: border .2s ease-in-out;

transition: border .2s ease-in-out;

}


.thumbnail .content {

padding: 3px;

font: 13px/18px 'BryantLGRegular';

color: #655c5a;

overflow: hidden;

}


.thumbnail .content .title {

font: 15px/18px 'BryantLGMedium';

margin-bottom: 7px;

color: #222222;

height: 36px;

max-height: 36px;

}


.thumbnail .content .desc {

padding: 3px;

font: 13px/18px 'BryantLGLight';

color: #655c5a;

overflow: hidden;

height: 72px;

max-height: 72px;

}


.thumbnail .new_badge {

width: 60px;

height: 60px;

background: url('../img/badge-new.png') no-repeat;

text-indent: -9999px;

position: absolute;

top: -10px;

left: -1px;

z-index: 20;

}


.thumbnail .image {

margin-bottom: 10px;

overflow: hidden;

position: relative;

z-index: 10;

}


.thumbnail .image .price {

position: absolute;

background-color: black;

color: white;

opacity: 0.8;

padding: 10px 20px;

font: 16px/16px 'BryantLGMedium';

font-weight: 600;

bottom: 5px;

right: 5px;

}


  - 적용한 productListItem.html 의 내용은 하기와 같다.

<div class="thumbnail">

<div th:if="*{featuredProduct}" class="new_badge">New!</div>


<div class="image">

<a th:href="@{*{url}}">

    <img th:if="*{media['primary']}" blc:src="@{*{media['primary'].url} + '?browse'}" th:alt="*{name}" />

    <div class="price" th:if="${#object instanceof T(org.broadleafcommerce.core.catalog.domain.ProductBundle)}">

        <div blc:price="*{salePrice}" th:if="*{onSale}" th:classappend="*{defaultSku.onSale}? 'sale'"></div>

        <div blc:price="*{retailPrice}" th:classappend="*{onSale}? 'has-sale'"></div>

    </div>

    <div class="price" th:unless="${#object instanceof T(org.broadleafcommerce.core.catalog.domain.ProductBundle)}">

        <div blc:price="*{defaultSku.salePrice}" th:if="*{defaultSku.onSale}" th:classappend="*{defaultSku.onSale}? 'sale'"></div>

        <div blc:price="*{defaultSku.retailPrice}" th:classappend="*{defaultSku.onSale}? 'has-sale'"></div>

    </div>

    </a>

    </div>

    

<div class="content">

  <div class="title" th:text="*{name}">Product Name</div>

<p class="desc" th:utext="*{longDescription}">description</p>

<p> 

<div th:class="*{'productActions productActions' + id}"

    th:with="checkInventory=*{defaultSku.inventoryType?.type == 'CHECK_QUANTITY'},

              availableInventory=${checkInventory ? #object.defaultSku.quantityAvailable != null and #object.defaultSku.quantityAvailable != 0 : true},

              inCart=${cart.containsSku(#object.defaultSku) and #lists.isEmpty(product.productOptions)}">

    <div th:if="${checkInventory and !availableInventory}" class="out_of_stock">

        <a disabled="disabled" class="inCart">Out of Stock</a>

    </div>

    <div class="btn btn-default" th:classappend="${!inCart}? ' hidden'" th:if="${#lists.isEmpty(product.productOptions)}">

        <a class="modalcart inCart" th:href="@{/cart}"><span th:text="#{product.inCart}">In Cart!</span></a>

    </div>

    <div class="add_to_cart" th:classappend="${inCart or !availableInventory}? ' hidden'">

        <blc:form method="POST" th:action="@{/cart/add}">

            <input type="hidden" name="productId" th:value="*{id}" />

            <input type="hidden" name="quantity" value="1" />

            <input type="hidden" name="hasProductOptions" th:value="*{!#lists.isEmpty(productOptions)}" />

            <input type="submit" class="btn btn-primary" th:value="#{product.buyNow}"/>

        </blc:form>

    </div>

</div>

</p>

    </div>

    

</div>


<div style="display: none;" th:id="*{'productOptions' + id}" class="product-options modal">

    <h3 th:text="*{name}"></h3>

    <div class="product-options" th:substituteby="catalog/partials/productOptions"/>

    <input type="button" class="addToCart" th:value="#{product.buyNow}" />

</div>


화면 구성이 되었다면 다음으로 2단 메뉴 구성을 해보자 

저작자 표시 비영리 변경 금지
Posted by peter yun 윤영식

티스토리 툴바