我如何保存"在DOM中更改其父级时的实体?

时间:2017-06-03 15:15:10

标签: aframe

我有一个"变量赋值"看起来如下的组件(附有黄色球体的蓝色菱形):

http://i.imgur.com/nJotPgW.gif(很遗憾,我没有足够的声誉来内嵌图片)

这里可以捕捉到的黄色球体是在变量赋值组件的初始化中创建的,如此

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'
    });
    ...

snap-site组件具有检测与红色球体碰撞的代码,然后将其作为子元素。所以在碰撞之前DOM看起来像这样。

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

之后

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

问题是当我想使用appendChild在另一个DOM元素内部使用变量赋值移动实体时,再次调用变量赋值的初始化函数,重置innerHTML。例如,如果我们有

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

我们希望使用类似containerElement.appendChild(variableAssignmentEntity)的内容将红色球体移除来将变量赋值移动到容器中

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

作为一个解决方法/ hack我正在考虑使用某种类型的标志来查看是否已经为元素/实体调用了initialize,该组件是属性,然后不运行初始化代码,如< / p>

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

但这似乎是一种糟糕的方法,并且也在查看A-Frame源代码似乎appendChild导致所有组件被删除然后再次添加,因此它实际上既不工作也不至少导致其他事情打破。

有没有一种好方法可以做到这一点,或者是否有不同的方法来定义变量赋值组件,因此黄色球体snap-site组件不是初始化中的子组件?

1 个答案:

答案 0 :(得分:2)

您确认appendChild导致组件重新初始化,并且可能无法按预期工作。以下是几种选择:

  1. 删除元素后,请调用el = el.cloneNode()制作一份干净的副本,然后附加该副本。
  2. 实际上,不要让球体成为您variable-assignment组件的子项,而只是拥有父母&#39;组件更新tick()函数中子项的位置/旋转。
  3. 使用底层的three.js API传递THREE.Object3D,而不实际更改任何元素的父级。
  4. (3)的一个例子:

    var mesh = el.getObject3D('mesh)';
    el.removeObject3D('mesh');
    otherEl.setObject3D('mesh', mesh);