다양한 프레임워크에는 목록 데이터를 DOM에 바인딩하는 기능이 있습니다. 예를 들어 Angular는 ng-repeat를 사용하여 바인딩합니다. 폴리머는 어떻습니까? 실제로 이 수준의 기능은 프레임워크의 확장이며 Angular의 ng-repeat는 단지 지시문일 뿐입니다. 폴리머의 돔-반복도 이 수준이다.
Polymer에서는 모든 것이 Directive 개념입니다. dom-module은 모듈을 정의하는 데 사용되며 그 자체가 지시문입니다. dom-repeat도 마찬가지지만 태그가 아니라 템플릿 태그를 기반으로 하는 지시문입니다. 다음과 같이 사용할 수 있습니다.
실행
<script> var Polymer = { dom: 'shadow' }; </script> <base href="http://www.web-tinker.com/share/" /> <link rel="import" href="polymer/polymer.html" /> <dom-module id="demo-test"> <template> <ul> <template is="dom-repeat" items="[[data]]"> <li> 第 <strong>[[index]]</strong> 项, 值为 <strong>[[item]]</strong> </li> </template> </ul> </template> <script> Polymer({ is: 'demo-test', properties: { data: { type: Array, value: [ 'a', 'b', 'c', 'd' ] } } }); </script> </dom-module> <demo-test></demo-test>
위 코드는 템플릿 요소의 is 속성을 dom-repeat로 설정하여 템플릿 요소의 내용이 반복됩니다. 이 루프는 템플릿 요소에 제공된 항목 속성을 기반으로 반복됩니다. 항목은 배열이어야 한다는 점에 유의하세요. 사용하기가 조금 불편할 수도 있지만 이 제한은 매우 좋은 습관이라고 생각합니다. Angular처럼 탐색하기 위해 for-in을 사용함으로써 발생하는 다양한 문제를 방지합니다.
항목의 각 항목에 대해 해당 인덱스와 값은 템플릿의 템플릿에서 사용할 수 있도록 index와 item 두 속성에 입력되므로 위의 예에서는 지정된 인덱스와 값을 출력합니다.
하지만 Polymer의 데이터 업데이트는 더티 데이터 비교를 기반으로 하지 않기 때문에 데이터의 동적 업데이트가 다소 번거로울 수 있습니다. 예를 들어 버튼이 있는 경우 클릭할 때마다 항목을 추가하려면 다음과 같이 작성해야 합니다.
실행
<script> var Polymer = { dom: 'shadow' }; </script> <base href="http://www.web-tinker.com/share/" /> <link rel="import" href="polymer/polymer.html" /> <dom-module id="demo-test"> <template> <input placeholder="请输入内容" value="{{value::input}}" /> <button on-click="append">添加一项</button> <ul> <template is="dom-repeat" items="[[data]]"> <li> 第 <strong>[[index]]</strong> 项, 值为 <strong>[[item]]</strong> </li> </template> </ul> </template> <script> Polymer({ is: 'demo-test', properties: { data: { type: Array, value: [ 'a', 'b', 'c', 'd' ] } }, append: function() { // data.push(this.value); // 这么写是不行的 this.push('data', this.value) } }); </script> </dom-module> <demo-test></demo-test>
앞서 Polymer에서는 변경 사항을 모니터링해야 하는 데이터를 접근자 속성으로 설정한다고 말씀드렸지만, 배열의 요소를 변경해도 실제로 배열 자체에는 변화가 없습니다. VM에 배열을 할당할 때 배열 개체를 거기에 던지는 대신 실제로 요소를 복사합니다. 즉, 이 배열 개체는 VM에 대한 직접적인 참조가 아닙니다. 이 배열 개체를 작동하면 VM에 영향을 미칠 수 없으므로 배열을 직접 푸시하는 것은 단지 데이터에 대한 푸시일 뿐입니다.
어레이 자체의 push 방식으로는 VM을 구동할 수 없지만, Polymer 자체에서도 VM을 직접 구동할 수 있는 몇 가지 메소드를 제공합니다. 예를 들어 위 예시의 this.push는 Polymer에서 제공합니다. 해당 작업 템플릿은 객체가 아니라 VM의 액세스 경로입니다(예를 들어 위 예에서 push의 첫 번째 매개변수 'data'는 VM의 데이터 액세스 경로입니다).
푸시 외에도 기본 메서드와 유사한 팝, 시프트 및 기타 작업도 있습니다(단, 요소 메서드가 아니라는 점에 유의하세요). 조작이 불편한 건 사실이지만, 어쨌거나 도저히 받아들일 수 없을 정도는 아니다.