Polymer, lego같이 만드는...
Transcript of Polymer, lego같이 만드는...
Polymer, LEGO같이 만드는 웹어플리케이션 재사용 가능한 UI, Polymer와 WebComponents
목차
• 배경 • 폴리머와 웹컴포넌트 사용하기 • 폴리머 실전 개발
배경
Dimitri Glazkov
2010년
2015년 지금 우리는…
탭을 사용하려면?
Tab UI를 만드는 5가지 방법.. 사실 더 많죠.
<paper-tabs> <paper-tab>KNOWLEDGE</paper-tab> <paper-tab>HISTORY</paper-tab> <paper-tab>FOOD</paper-tab></paper-tabs>
더 적은 코드. 덜 혼란스럽게.Web Components
Custom Elements컴포넌트가 인터페이스를 가진 DOM Element 형태로 사용될 수 있도록...
Templates컴포넌트의 골격이 사용하기 전까지 비활성화된 상태로 관리되도록...
Shadow DOM컴포넌트의 스타일, DOM의 표현을 캡슐화하여 처리할 수 있도록...
HTML Imports위의 요소들을 포함한 리소스(Markup, JS, CSS)를 로딩할 수 있도록...
웹 컴포넌트의 구성과 배포에 적합한 4가지 규격
하지만 적은 브라우저 지원…
\
Custom Elements HTML Imports
Shadow DOMTemplates
webcomponents.js
• webcomponents.js 모든 스펙이 대한 polyfills 제공
• webcomponents-lite.js Shadow DOM을 제외한 polyfills 제공
폴리머와 웹 컴포넌트 사용하기
polymer는 라이브러리.
웹 컴포넌트 기반 어플리케이션을 쉽고, 빠르게 만들게 해준다.
polymer.js= 더 편리하게sugaring
Custom Elements새로운 HTML/DOM 요소를 정의
Custom Elements사용자정의 엘리먼트의 등록
var PatternProto = Object.create(HTMLElement.prototype);
PatternProto.createdCallback = function() { this.innerHTML = "...";};
var Widget = document.registerElement('x-pattern', { prototype: ScaffoldProto});
웹컴포너트 API
polymer
Custom Elements사용자정의 엘리먼트의 등록
<polymer-element name="x-pattern"> <script> Polymer({ }); </script></polymer-element>
<x-pattern></x-pattern>
Custom Elements사용자정의 엘리먼트의 사용
Templates클라이언트 쪽 네이티브 템플릿화
polymer
<polymer-element name=“user-list” noscript> <template> <ul> <template repeat=“{{user, i in users}}”> <li>{{user.name}}</li> </template> </ul> </template></polymer-element>
<template> …</template>
Templates템플릿 처리
Shadow DOMDOM/CSS 스콥핑
출처: https://docs.google.com/presentation/d/1SZ05jFRF9Rfsrn39z5-vdyLbY37XZGEgQfZ1uIOaEEo/edit#slide=id.g6352514f4_423
<div><h3>Light DOM</h3></div> <script> var root = document.querySelector('div').createShadowRoot(); root.innerHTML = '<style>h3{ color: red; }</style>' + '<h3>Shadow DOM</h3>'; </script>
Shadow DOM
Shadow DOM지정된 DOM을 정의한 DOM 트리로 렌더링
<div>Content new Shadow DOM</div> <script> var root = document.querySelector('div').createShadowRoot(); root.innerHTML = '<style>h3{ color: red; }</style>' + '<h3><content></content></h3>'; </script>
Shadow DOM콘텐츠와 프레젠테이션의 분리
o <content></content>
<div>Content new Shadow DOM<h3>Im the one</h3></div> <script> var root = document.querySelector('div').createShadowRoot(); root.innerHTML = '<style>h3{ color: red; }</style>' + '<h3><content select=”.the-one”></content></h3>'; </script>
Shadow DOM콘텐츠와 프레젠테이션의 분리
o <content></content> o <content select=”<SELECTOR>”></content>
var shadow = el.createShadowRoot();shadow.innerHTML = “<style>h2 { color: red; }</style>” + “<h2>I’m a profile-card</h2>”;
<polymer-element name=“profile-card” noscript> <template> <link rel=“stylesheet” href=“styles.css”> <h2>I’m a profile-card</h2> </template></polymer-element>
polymer
Shadow DOMCustom Element 등록 시 자동 적용
웹컴포넌트 API
HTML Importsweb components 로딩
HTML import웹 컴포넌트 로딩
<script src="bower_components/webcomponentsjs/webcomponents.js"></script><link rel="import" href="elements/x-element.html">
<link rel="import" href="../bower_components/polymer/polymer.html"><link rel="import" href="../bower_components/core-scaffold/core-scaffold.html"><link rel="import" href="../bower_components/core-header-panel/core-header-panel.html"><link rel="import" href="../bower_components/paper-input/paper-input.html"><link rel="import" href="../bower_components/paper-fab/paper-fab.html">
index.html
x-element.html
polymer=웹컴포넌트 API
만들어 가면서 알아봅시다.
폴리머 실전개발
자주 사용되는 화면 패턴목록형으로 데이터를 보여주는 화면
타이틀 타이틀
자주 사용되는 화면 패턴목록형으로 데이터를 보여주는 화면
타이틀
<x-pattern>
자주 사용되는 화면 패턴목록형으로 데이터를 보여주는 화면
타이틀
????
????
????
????
????
core-elements
Layout Elements자식 요소의 위치를 배치하는 요소
<core-drawer-panel>왼쪽/오른쪽 드로우어 패널이 있는 레이아웃
<polymer-element name="x-pattern"> <template> <core-drawer-panel> <core-header-panel drawer mode="seamed"></core-header-panel> <core-header-panel main> <core-toolbar> <core-icon icon="menu" core-drawer-toggle></core-icon> <div flex>title</div> </core-toolbar> </core-header-panel> </core-drawer-panel> </template><script> Polymer(‘x-pattern’,{ }); </script></polymer-element>
core-drawer-panel
core-header-panel
core-header-panel
core-toolbar
1
2
4
5
3
<polymer-element name="x-pattern"> <template> <core-scaffold> <core-header-panel navigation flex mode="seamed"> </core-header-panel> <div tool> <div>title</div> </div> <div class="content"> </div> </core-scaffold> </template> <script> Polymer(‘x-pattern’,{ }); </script></polymer-element>
core-scaffoldcore-toolbar
core-header-panel
<core-scaffold>반응형 앱을 위한 퀵스타트 레이아웃
1
2
3
4
그 외에 다른 <core-elements>
…….
이제 안쪽 컴포넌트들을
채워볼가요?
paper-elements
타이틀
<x-pattern-item>
<!-- ... 생략 ... --><link rel="import" href="x-pattern-item.html"><polymer-element name="x-pattern" attributes="items"> <template> <core-scaffold> <core-header-panel navigation flex mode="seamed"> </core-header-panel> <div tool layout horizontal flex> <div>title</div> </div> <div class="content"> <div class="item-list"> <x-pattern-item></x-pattern-item> <x-pattern-item></x-pattern-item> <x-pattern-item></x-pattern-item> <x-pattern-item></x-pattern-item> </div> </div> </core-scaffold> <style>
/* ... 생략 ... */ </style> </template> <script> Polymer('x-pattern',{ }); </script></polymer-element>
<x-pettern>에서 새로 정의한 <x-pattern-item> 사용
z축의 깊이와 공간적 관계를 변경하는 동적 쉐도우dynamic shadow
<paper-shadow>
<polymer-element name="x-pattern-item"> <template> <paper-shadow z="1"> </paper-shadow> <style> paper-shadow { margin: 10px; padding: 10px; background: #fff; min-height: 50px; } </style> </template> <script> Polymer("x-pattern-item",{
}); </script></polymer-element>
paper-shadow
1
터치와 마우스 엑션을 나타내는 반응적 잉크 효과reactive ink effect
<paper-ripple>
<polymer-element name="x-pattern-item"> <template> <paper-shadow z="1"> <paper-ripple fit></paper-ripple> </paper-shadow> <style> paper-shadow { margin: 10px; padding: 10px; background: #fff; min-height: 50px; } </style> </template> <script> Polymer({ }); </script></polymer-element>
1
타이틀
????
<paper-input>사용자 입력을 위한 한 줄 입력 필드
<!-- ... 생략 ... --><link rel="import" href="x-pattern-item.html"><polymer-element name="x-pattern" attributes="items"> <template> <core-scaffold> <core-header-panel navigation flex mode="seamed"> </core-header-panel> <div tool layout horizontal flex> <div>title</div> </div> <div class="content"> <div class="item-list"> <x-pattern-item></x-pattern-item> </div> <div class="input-box" layout horizontal> <paper-input flex label="입력하세요..." id="input"></paper-input> </div> </div> </core-scaffold> /* ... 이하 생략 ... */
1
<!-- ... 생략 ... --><link rel="import" href="x-pattern-item.html"><polymer-element name="x-pattern" attributes="items"> <template> <core-scaffold> <core-header-panel navigation flex mode="seamed"> </core-header-panel> <div tool layout horizontal flex> <div>title</div> </div> <div class="content"> <div class="item-list"> <x-pattern-item></x-pattern-item> </div> <div class="input-box" layout horizontal> <paper-input flex label="입력하세요..." id="input"></paper-input> <paper-fab icon="polymer" self-center mini></paper-fab> </div> </div> </core-scaffold> /* ... 이하 생략 ... */
<paper-fab>fab는 floating action button을 의미하고 기본적으로 반응적 잉크 효과가 적용됨
1
다른 paper-elements
정적 동적
data binding
<polymer-element>로 정의한 요소는 모델 그 자체이다.
<polymer-element name="x-pattern"> <template> <core-scaffold> <core-header-panel navigation flex mode="seamed"> </core-header-panel> <div tool layout horizontal flex> <div title>{{patternName}}</div> </div> <div class="content" layout vertical fit> <div class="item-list" flex> <x-pattern-item></x-pattern-item> </div> <!-- 생략 --> </core-scaffold> </template> <script> Polymer("x-pattern",{ patternName : "pattern-x" }); </script></polymer-element>
템플릿 안에서 이중 중갈호({{ }})를 이용하여 컴포넌트와 속성값을 바인딩Data Binding
1
2
<polymer-element name="x-pattern"> <template> <core-scaffold> <!—- 생략 … —-> <div class="content" layout vertical fit> <div class="item-list" flex> <template repeat="{{items}}" class="item-list" flex> <x-pattern-item> </x-pattern-item> </template> </div> <div class="input-box" layout horizontal> <paper-input flex label="입력하세요..." id="input"></paper-input> <paper-fab icon="polymer" self-center mini></paper-fab> </div> </div> </core-scaffold> </template> <script> (function() { var items = [{text:"hello"},{text:"hello"},{text:"hello"}]; Polymer({ patternName : "pattern-x", ready: function() { this.items = items; } }); })(); </script></polymer-element>
반복적인 데이터 표현Data Binding
3
1
2
<polymer-element name="x-pattern"> <template> <core-scaffold> <!-- 생략 ... --> <div class="content" layout vertical fit> <div class="item-list" flex> <template repeat="{{items}}" class="item-list" flex> <x-pattern-item></x-pattern-item> </template> </div> <div class="input-box" layout horizontal> <paper-input flex label="입력하세요..." id="input" value="{{input}}"></paper-input> <paper-fab icon="polymer" self-center mini on-tap="{{addItem}}"></paper-fab> </div> </div> </core-scaffold> </template> <script> (function() { var items = [{text:"hello"},{text:"hello"},{text:"hello"}]; Polymer({ patternName : "pattern-x", ready: function() { this.items = items; }, addItem : function () { this.items.push({ text : this.input }); this.input = ''; } }); })(); </script>
이벤트 바인딩 & Dom 노드의 값과 모델 데이터 양방향 바인딩Data Binding
3
1
2
공개 속성 데이터 바인딩Data Binding
<polymer-element name="x-pattern-item" attributes="item"> <template> <paper-shadow z="1" animated layout horizontal center> <div flex>{{item.text}}</div> <paper-ripple fit></paper-ripple> </paper-shadow> <style> paper-shadow {
margin: 10px;padding: 10px;background: #fff;min-height: 50px;
} </style> </template> <script> Polymer("x-pattern-item",{ }); </script></polymer-element>
1
2
x-pattern-item.html
공개 속성 데이터 바인딩Data Binding
x-pattern.html
<polymer-element name="x-pattern"> <template> <core-scaffold> <!-- 생략 --> <div class="content" layout vertical fit> <div class="item-list" flex> <template repeat="{{textItem in items}}" class="item-list" flex> <x-pattern-item item="{{textItem}}"> </x-pattern-item> </template> </div> <!-- 생략 --> </div> </core-scaffold> </template> <script>
//생략.. </script></polymer-element>
1
2
정의한 패턴 컴포넌트를 활용하여 TODO 앱 만들어 보기
customelements.io
<app-router>github.com/erikringsmuth/app-router
my-site.com/order/:id
<app-router> <!-- matches an exact path --> <app-route path="/home" import="/pages/home-page.html"></app-route>
<!-- matches using a path variable --> <app-route path="/order/:id" import=“/pages/order-page.html"></app-route></app-router>
<page-er>github.com/addyosmani/page-er
<page-er perpage="5" previous=“<< Previous" next=“Next >>"></page-er>
var pager = document.querySelector("page-er");document.addEventListener("polymer-ready", function() { pager.data = model.items;});
<ajax-form>github.com/garstasio/ajax-form
Full Name
Country City
Join newsletter
<form is="ajax-form" action="my/form/handler"> <label>Full Name <input type="text" name=“full_name"> </label> …</form>
√
EXPLORE
<thank-you>