Функция запуска пользовательского компонента перед загрузкой el, но перед отправкой загруженного события - PullRequest
0 голосов
/ 03 января 2019

Я пишу пользовательскую функцию, которая требует инициализации всех компонентов (включая себя).

После инициализации всех компонентов, но перед отправкой загруженного события, я хочу запустить некоторую пользовательскую логику над el и затем освободить загруженное событие.

Есть ли способ справиться с этим, и есть ли пользовательское событие, например, "компоненты загружены"

Я пытаюсь избежать загруженного события, так как это будет мешать другой логике, которая требует это событие, все еще контролируя дом.

AFRAME.registerComponent('cool-component', {
  init: function() {
    this.preloadBound = this._preload.bind(this);
    this.el.addEventListener('components-loaded', this.preloadBound, {once: true});
    this.el.addEventListener('componentinitialized', this.preloadBound, {once: true});
    this.el.addEventListener('componentchanged', this.preloadBound, {once: true});
    this.el.addEventListener('componentremoved', this.preloadBound, {once: true});
    this.el.addEventListener('child-attached', this.preloadBound, {once: true});
    this.el.addEventListener('child-detached', this.preloadBound, {once: true});
    this.preloaded = false; <-- CREATED BOOL FLAG
  },
  _preload: function() {
    //do some work here
    this.preloaded = true;
  }
  exposed:function(){ <-- UPDATED THIS FUNCTION
    return new Promise((resolve,reject)=>{
      if(!this.preloaded){
        setTimeout(() => {
          this.exposed().then(resolve);
        }, 200);
      }
      else{
        //do some work based on the work done in the preload
        resolve()
      }
    });
  }  
});

1 Ответ

0 голосов
/ 03 января 2019

Вы можете использовать события вместо таймера - генерировать событие, когда предварительно загруженный материал сделан:

 _preload: function() {
  //do some work here
  emit('preloaded_done')
  this.preloaded = true;
},
exposed:function(){ 
  if (!this.preloaded) {
   this.el.addEventListener('preloaded_done', this.exposed)
   return;
  }
  // all things that are needed to be done after the preload
}

Таким образом, открытая функция будет выполнена после того, как предварительно загруженный материал будет сделан.


Или вы можете хранить события в массиве

init: function() {
  // ... binds and stuff
  this.cachedEvents = []
  this.el.addEventListener('loaded', this.cacheEvents)
  stuffBeforeEmittingEvents()
},
cacheEvents: function(e) {
  this.cachedEvents.push(e)
  this.el.removeEventListener(e.type, this.cacheEvents)
  e.stopPropagation()
}

и, как только вы сделаете свои вещи, просто выполните цикл и испустите их

for(i = 0; i < this.cachedEvents.length;  i++) {
    this.el.emit(this.cachedEvents[i].type, this.cachedEvents[i])
}


Что-то вродеэто:
init: function() {
 this.events = []
 this.stuff = this.stuff.bind(this);
 this.cacheEvents = this.cacheEvents.bind(this);
 this.emitCachedEvents = this.emitCachedEvents.bind(this);

 this.el.addEventListener('loaded', this.cacheEvents)
 this.stuff()
},
stuff: function() {
  // whatever you need to do
  this.emitCachedEvents()
},
cacheEvents(e) {
 this.events.push(e)
 // prevent bubbling + catching the same event
 this.el.removeEventListener(e.type, this.cacheEvents)
 e.stopPropagation()
},
emitCachedEvents() {
   for (let i = 0; i < this.events.length; i++) {
      // primitive, may require polyfill - emit(name, data)
      emit(this.events[i].type, this.events[i])
   }
}

Проверьте это в моей скрипке .

...