简体   繁体   中英

Aurelia Custom Attribute with setAttribute method()

It seems Aurelia is not aware when I create and append an element in javascript and set a custom attribute (unless I am doing something wrong). For example,

const e = document.createElement('div');
e.setAttribute('custom-attr', 'some value');
body.appendChild(e);

Is there a way to make Aurelia aware of this custom attribute when it gets appended?

A little background: I am creating an app where the user can select their element type (eg input, select, checkbox etc.) and drag it around (the dragging is done in the custom attribute). I thought about creating a wrapper <div custom-attr repeat.for="e of elements"></div> and somehow render the elements array, but this seemed inefficient since the repeater will go through all the elements everytime I push a new one and I didn't not want to create a wrapper around something as simple as a text input that might be created.

You would have to manually trigger the Aurelia's enhance method for it to register the custom attributes or anything Aurelia related really. And you also have to pass in a ViewResources object containing the custom attribute.


Since this isn't as straight forward as you might think, I'll explain it a bit.

The enhance method requires the following parameters for this scenario:

  • Your HTML as plain text (string)
  • The binding context (in our scenario, it's just this )
  • A ViewResources object that has the required custom attribute

One way to get access to the ViewResources object that meets our requirements, is to require the custom attribute into your parent view and then use the parent view's ViewResources . To do that, require the view inside the parent view's HTML and then implement the created(owningView, thisView) callback in the controller. When it's fired, thisView will have a resources property, which is a ViewResources object that contains the require -d custom attribute.

Since I am HORRIBLE at explaining, please look into the example provided below.


Here is an example how to:

app.js

import { TemplatingEngine } from 'aurelia-framework';

export class App {
  static inject = [TemplatingEngine];

  message = 'Hello World!';

  constructor(templatingEngine, viewResources) {
    this._templatingEngine = templatingEngine;
  }

  created(owningView, thisView) {
    this._viewResources = thisView.resources;
  }

  bind() {
    this.createEnhanceAppend();
  }

  createEnhanceAppend() {
    const span = document.createElement('span');
    span.innerHTML = "<h5 example.bind=\"message\"></h5>";
    this._templatingEngine.enhance({ element: span, bindingContext: this, resources: this._viewResources });
    this.view.appendChild(span);
  }
}

app.html

<template>
  <require from="./example-custom-attribute"></require>

  <div ref="view"></div>
</template>

Gist.run:

https://gist.run/?id=7b80d2498ed17bcb88f17b17c6f73fb9


Additional resources

Dwayne Charrington has written an excellent tutorial on this topic:

https://ilikekillnerds.com/2016/01/enhancing-at-will-using-aurelias-templating-engine-enhance-api/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM