Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Template Instantiation

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for koba04 koba04
November 15, 2017

Template Instantiation

Avatar for koba04

koba04

November 15, 2017
Tweet

More Decks by koba04

Other Decks in Programming

Transcript

  1. w IUUQTHJUIVCDPNXDXFCDPNQPOFOUTCMPCHIQBHFT QSPQPTBMT5FNQMBUF*OTUBOUJBUJPONE w IUUQTXXXXPSHXFCQMBU NJOVUFTIUNMJUFN w 1SPQPTFECZ"QQMF !SOJXB PO/PWFNCFSTU

     w 5FNQMBUF*OTUBOUJBUJPOJTBQSPQPTBMUPQSPWJEFBOBUJWF NFDIBOJTNUPJOTUBOUJBUFBUFNQMBUFFMFNFOUXJUITPNFQBSUT CBTFEPO+BWB4DSJQUWBMVFT w 5FNQMBUF OPU$PNQPOFOU 8IBUJT5FNQMBUF*OTUBOUJBUJPO
  2. w 4IPVMECFBCMFUPVQEBUFJUTTIBEPXUSFFXIFOUIF DPSSFTQPOEJOH+4WBMVFTBSFVQEBUFE 6TF$BTF <template> <div> <span>{{id}}</span> <span>{{name}}</span> </div> </template>

    const templateInstance = template.createInstance({ id: 100, name: ‘foo’ }); templateInstance.update({id: 100, name: ‘bar’});
  3. w 4IPVMECFBCMFUPDBMMBGVODUJPOXJUI+4WBMVFTCFGPSFJU HFUTJOTFSUFEJOUPUIFUFNQMBUFJOTUBODF 6TF$BTF var obj = {id: 100, name:

    ‘foo’} <template> <div> <span>{{id}}</span> <span>{{capitalize name}}</span> </div> </template>
  4. w 4IPVMECFBCMFUPTFUBOESFNPWFBOBUUSJCVUFCBTFEPO +4WBMVFT 6TF$BTF var obj = {id: 100, name:

    ‘foo’} <template> <div> <span>{{id}}</span> <input type=“checkbox” checked /> <!— or —> <input type=“checkbox” /> </div>
  5. #BTJDT [NoInterfaceObject] Interface TemplateInstance : DocumentFragment { void update(any state);

    }; partial interface HTMLTemplateElement { TemplateInstance createInstance(optional any state); } const template = document.getElementById(‘my-template’); const state = {count: 1}; const instance = template.createInstance(state); shadowRoot.appendChild(instance); state = {count: state.count + 1}; instance.update(state);
  6. w "OFYQSFTTJPOJOFBDINVTUBDIFDSFBUFTB5FNQMBUF 1BSUTPCKFDU 5FNQMBUF1BSUT // name = ‘foo’; <template> <div>{{capitalize

    name}}</div> </template> // templatePart.expression = “capitalize name”; // … // templatePart.value = “Foo”; // or // templatePart.replace([dom1, dom2]); // or // templatePart.replaceHTML(‘<em>Foo</em>’);
  7. 5FNQMBUF1BSUT interface TemplatePart { readonly attribute DOMString expression; attribute DOMString?

    value; stringilyer; } interface AttributeTemplatePart : TemplatePart { readonly attribute Element element; readonly attribute DOMString attributeName; readonly attribute DOMString attributeValue; attribute boolean booleanValue; } interface NodeTemplatePart : TemplatePart { readonly attribute ContainerNode parentNode; readonly attribute Node? previousSibling; readonly attribute Node? nextSibling; [NewObject] readonly NodeList replacementNode; void replace((Node or DOMString)… nodes); void replaceHTML(DOMString html); }
  8. w &BDIUFNQMBUFUZQFJTBTTPDJBUFEXJUI 5FNQMBUF1SPDFTT$BMMCBDL 5FNQMBUF1SPDFTT$BMMCBDL interface HTMLTemplateElement { attribute DOMString type;

    }; callback TemplateProcessCallback = void (TemplateInstance, sequence<TemplatePart>, any state); dictionary TemplateTypeInit { TemplateProcessCallback processCallback; TemplateProcessCallback? createCallback; }
  9. w :PVDBOEFpOFBGVODUJPOUPQSPDFTTUFNQMBUFQBSUTCZ UFNQMBUFQSPDFTTDBMMCBDL 5FNQMBUF1SPDFTT$BMMCBDL <my-template>…</template> <script> document.defineTemplateType(“my-template”, { createCallback: (instance,

    parts, state) => { // How do I remove the event listener? listen(‘change’, () => instance.update(state)); }, // default processor is something like this. processCallback: (instance, parts, state) => { for (const part of parts) { part.value = state[part.expression]; } } });
  10. 5FNQMBUF1SPDFTT$BMMCBDL <template type=“loop”> <ul> <template directive=“foreach” expression=“items”> <li>{{name}}</li> </template> </ul>

    </template> document.defineTemplateType(‘loop’, { processCallback: (instance, parts, state) => { for (const part of parts) { if (part instance InnerTemplatePart) { switch (part.directive) {
 case ‘foreach’: part.replace( state[expression] .map(item => part.template.createInstance(item)) ); break; } }
  11. w )5.-UFNQMBUFT WJB+BWB4DSJQUUFNQMBUFMJUFSBMT MJUIUNM 1PMZNFS-BCT import {html, render} from ‘./node_modules/lit-html/lit-html.js’;

    import {repeat} from ‘./node_modules/lit-html/lib/repeat.js’; const items = [{id: 1, name: ‘foo’}, {id: 2, name: ‘bar’}]; render( html` <ul> ${repeat(items, (item) => item.id, (item) => html`<li>${item.name}</li>` } </ul> `, document.querySelector(‘items’) );
  12. w 'BTUBOEMJHIUXFJHIU6*DPNQPOFOUTGPSUIFXFC w )BOEMFCBST)5.-#BST(MJNNFS w 7."SDIJUFDUVSF w "QQFOEBOE6QEBUFPQFSBUJPO w #JOBSZUFNQMBUFT

    (MJNNFSKT &NCFS Handlebars Template ! Compile IR(Intermediate Representation) -> Opcodes ! VM executes opcodes Browser, Node