2017-07-31 6 views
0

私は現在2つのコンポーネントを持っています。それらのうちの1つは、一連の12面体を作成し、もう1つは非表示にします。両方とも実行時に生成されます。A-Frameの別のコンポーネントから動的に作成された子にアクセスする

問題は目に見えないものです。

el.querySelector('*') 

を目に見えない部品のinit方法では:私が使用して、動的に生成された子を取得することはできません。

私も試してみました:

  • は「ロードされた」イベントを受け取ると、コンポーネントを登録します。
  • 約束を使用して、ロードされたイベントをリッスンします。
  • コンポーネントが登録されてから3秒後にwindow.setTimeout()関数を使用する。

これはこれまでのところ、私の完全なコードです:私はそれが実体の子供たちを探して動作させることはできませんいくつかの理由

export class InvisibleComponent { 
    constructor() { 
    /** 
    * Sets the current element and all of its children as invisible 
    * by using its materials property. 
    * 
    */ 
    const _this = this; 
    AFRAME.registerComponent('invisible', { 
     init: function() { 
     _this.setTransparent(this.el); 
     console.log(this.el); 
     let children = this.el.querySelector('*'); 
     if (!children) return; 
     Array.from(children).forEach(child => { 
      _this.setTransparent(this.el); 
     }) 
     }, 
     remove: function() { 
     if (!this.el) return; 
     _this.setOpaque(this.el); 
     let children = this.el.querySelector('*'); 
     if (!children) return; 
     Array.from(children).forEach(child => { 
      _this.setOpaque(this.el); 
     }) 
     } 
    }) 
    } 
    setTransparent(el: AFrame.Entity) { 

    this.getMaterial(el).then((material :any) => { 
     this.setAttributes(el,material.opacity); 
    }) 
    .catch(resolve => { 
     console.log("Material couldn't be gathered. Using 100% of opacity instead", resolve); 
     this.setAttributes(el, 1); 
    }); 
    } 

    setAttributes(el : AFrame.Entity, opacity){ 
    el.setAttribute('data-previous-opacity',opacity); 
    el.setAttribute('material', 'opacity:0; transparent: true; visible:false;'); 
    } 

    /** 
    * This is a solution if the element which is trying to load 
    * hasn't been loaded yet. All elements must have a material 
    * in order to be inserted in a scene. 
    * @param el 
    */ 
    getMaterial(el: AFrame.Entity): Promise<number> { 
    return new Promise<number>((resolve, reject) => { 
     let material = el.getAttribute('material'); 
     if (material) resolve(material); 

     el.sceneEl.addEventListener('loaded', function() { 
     let material = el.getAttribute('material'); 
     !material ? reject(undefined) : resolve(material); 
     }) 


    }); 
    } 

    // If you had previous property, this will not remove them. 
    setOpaque(el: AFrame.Entity) { 
    let dataPreviousOpacity = el.getAttribute('data-previous-opacity'); 
    if (!dataPreviousOpacity) dataPreviousOpacity = 1; 
    el.setAttribute('material', 'transparent', dataPreviousOpacity === 1 ? false : true); 
    el.setAttribute('material', 'opacity', dataPreviousOpacity); 
    el.setAttribute('material', 'visible', true); 

    } 
} 
+1

コンポーネントは実行時に登録するのではなく、読み込み時に登録する必要があります。子供が添付されたイベントは、すべての子が読み込まれたことを検出し、他のコンポーネントがそのイベントをリッスンするようにすると、イベントを出力します。あるいは、setTimeoutsもうまくいくはずです。分割不可能なコンポーネントを12面体発生器を依存関係にするのに役立つでしょう – ngokevin

+0

@ngokevin:意味があります。私はこのアプローチをチェックアウトします。どうも。私が持っている別の問題を解決し終えるとポストバックします(全く異なる問題) –

答えて

2

。ここで
は私のアプローチです:

  1. 作成された要素公開:

    init:function(){ 
        //expose the object: 
        this.object = document.createElement('a-dode(..)') 
    } 
    
  2. アクセスをel.components.componentName.object

を使用して、オブジェクトがしかしそれはあなたが好きで、オブジェクトの公開配列にすることができます。 undefinedオブジェクトにアクセスする際に問題はないようです。もしあなたが持っていれば、オブジェクトが未定義であるかどうかを確認したり、配列をループしたりして、それぞれの 'undefinedでない要素'に対して 'set invisible'を実行することができます。

作業フィルドhere:コンポーネント 'create'はボックスを作成し、 'change_color'は色+位置を設定します。 getObject()関数もあります。私のアプローチでは重大なセキュリティ問題があり、おそらくオブジェクトに適切なゲッターが必要になるため、後で説明します。


私が言及した「セキュリティ問題」の適切な方法は何かわからないんだけど、私は bind();を使用してゲッターにオブジェクトを渡すと、「ゲッター」を作ることができた:

init: function(){ 
    object = (...); 
    this.getObject = this.getObject.bind(this,[object]); 
}, 
getObject(){ 
    return arguments[0]; 
} 

これが恐ろしく、それ以外の方法で対処されているはずだったら、私に知らせてください。
おそらく私はget getterName(){//getterBody}を使うべきですが、それは私にいくつかのエラーを投げます。
フィドルhereが更新されました。

+0

面白いです。ヘッドアップをありがとう。これはうまくいくかもしれない。) –

+0

@JoseA確かに、幸運:) –

+0

私がやっていることに自分自身を逸脱している間、el.componentsに問題があります。 componentName.objectは、componentNameがアクセスしている瞬間に定義されていないようだからです。 –

関連する問題