How do I "preserve" an entity when changing its parent in the DOM?

Viewed 333

I have a "variable assignment" component that looks like the following (the blue diamond with the yellow sphere attached):

http://i.imgur.com/nJotPgW.gif (unfortunately I don't have enough reputation to inline the image)

Here the yellow sphere that things can snap into is created in the initialization of the variable assignment component like so

AFRAME.registerComponent('variable-assignment', {
  schema: {
    grabbable: {default: true}
  },
  init: function () {
    this.el.innerHTML = `
    <a-sphere
    snap-site="controller:#right-hand"
    radius=".1"
    color="yellow"
    material="transparent:true; opacity:.5;"
    position=".22 0 0">
    </a-sphere>
    `;
    this.label = 'x';
    this.el.setAttribute('geometry', {
      primitive: 'octahedron',
      radius: .1,
      color: 'blue'
    });
    ...

The snap-site component has code that detects a collision with the red sphere and then makes it a child element. So the DOM looks something like this before the collision.

<a-sphere color=red></a-sphere>
<a-entity variable-assignment>
    <a-sphere snap-site>
    <a-sphere>
</a-entity>

and after

<a-entity variable-assignment>
    <a-sphere snap-site>
        <a-sphere color=red></a-sphere>
    <a-sphere>
</a-entity>

The problem is when I want to move the entity with variable-assignment inside another DOM element using appendChild the initialization function for the variable-assignment called again the innerHTML is reset. So for example if we have

<a-entity container></a-entity>
<a-entity variable-assignment>
    <a-sphere snap-site>
        <a-sphere color=red></a-sphere>
    <a-sphere>
</a-entity>

And we want to move variable-assignment into container using something like containerElement.appendChild(variableAssignmentEntity) the inner red sphere gets removed

<a-entity container>
    <a-entity variable-assignment>
        <a-sphere snap-site>
        <a-sphere>
    </a-entity>
</a-entity>

As a work around/hack I was thinking about using a flag of some sort to see if initialize had already been called before for the element/entity the component was a property of and then not run the initialization code, something like

  init: function () {
    if (this.el.getAttribute('initialized')) {
        return;
    } 
    this.el.setAttribute('initialized', true);
    ...

but this seems like a bad way to do it and also looking into the A-Frame source it seems appendChild causes all components to be removed then added again so it doesn't actually work either or at least causes other things to break.

Is there a good way to do this or is there a different way to define the variable-assignment component so the yellow sphere snap-site component isn't a child set in the initialization?

1 Answers
Related