Aurelia - Inline definition of HTML-only custom element

前端 未结 1 2173
南笙
南笙 2021-02-20 12:48

I have a recursive object in my Aurelia view model that looks like this:

Class BottomlessPit {
    Name: string = \'\';
           


        
相关标签:
1条回答
  • 2021-02-20 13:24

    OK this hurt my head a little bit but here's a way to enable defining inline html-only custom elements...

    https://gist.run?id=11ac077048cab0ad9979

    app.html

    <template>
      <h1>Aurelia - Inline Custom Elements</h1>
    
      <template name="person-element" bindable="person">
        <h3>${person.name}</h3>
        <person-element repeat.for="parent of person.parents" person.bind="parent"></person-element>
      </template>
    
      <template name="hello" bindable="message">
        ${message}
      </template>
    
      <person-element person.bind="kid"></person-element>
    
      <hello message="hello world"></hello>
    </template>
    

    app.js

    export class App {
      kid = {
        name: 'North West',
        parents: [
          {
            name: 'Kanye West',
            parents: []
          },
          {
            name: 'Kim Karsomething',
            parents: []
          }
        ]
      };
    }
    

    main.js

    import {relativeToFile} from 'aurelia-path';
    import {Origin} from 'aurelia-metadata';
    import {TemplateRegistryEntry, TemplateDependency} from 'aurelia-loader';
    
    // override the TemplateRegistryEntry's "template" property, adding
    // logic to process inline custom elements (eg <template name="foo">)
    let templateDescriptor = Object.getOwnPropertyDescriptor(TemplateRegistryEntry.prototype, 'template');
    Object.defineProperty(TemplateRegistryEntry.prototype, 'standardTemplate', templateDescriptor);
    Object.defineProperty(TemplateRegistryEntry.prototype, 'template', {
      get: function get() {
        return this.standardTemplate;
      },
      set: function set(value) {
        // hand off to the standard template property...
        this.standardTemplate = value;
    
        let address = this.address;
    
        // loop through each of the inline custom elements and register
        // them as dependencies.
        let namedTemplates = value.content.querySelectorAll('template[name]:not([name=""])');
        for (var i = 0, ii = namedTemplates.length; i < ii; ++i) {
          let current = namedTemplates[i];
          let name = current.getAttribute('name');
          let id = relativeToFile(`./${name}.html`, address); // potential for collision but putting in subfolder would be weird if the inline element had it's own <require> elements
    
          // give the loader the template html
          System.set(
            id + '!' + System.normalizeSync('text'),
            System.newModule({ __useDefault: true, default: current.outerHTML}));
    
          // register the dependency
          this.dependencies.push(new TemplateDependency(id, name));
    
          // remove the inline template element from the template
          current.parentNode.removeChild(current);
        }
      }
    });
    
    export function configure(aurelia) {
      aurelia.use
        .standardConfiguration()
        .developmentLogging();
    
      aurelia.start().then(() => aurelia.setRoot());
    }
    
    0 讨论(0)
提交回复
热议问题