我目前有2個組件。其中一個創建了一系列十二面體,另一個則隱藏了它們。它們都是在運行時生成的。從A幀中的其他組件訪問動態創建的子項目
問題在於看不見的問題。在可見組件的init
方法
el.querySelector('*')
:我無法使用得到的動態生成的孩子。
我甚至試過:
- 監聽「裝」事件,然後註冊該組件。
- 使用承諾並收聽加載的事件。
- 在組件註冊後使用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);
}
}
組件不應該在運行時註冊,而應該在頁面加載。當你檢測到所有的孩子被加載並且讓其他組件監聽那個事件時,附屬於孩子的事件應該會有幫助,發出一個事件。或者setTimeouts也應該工作。將有助於將不可分割的組件設置爲十二面體生成器作爲依賴關係 – ngokevin
@ngokevin:有道理。我也會檢查這個方法。謝謝。一旦我完成解決我有另一個問題後會回發(完全不同的問題) –