pageInit and sub-components

I’ve run into this situation in another instance that I can’t recall at the moment, but when declaring sub-components with JSX in core, it seems like they’re not necessarily initialized when page:init fires.

In this case, I’m trying to use a preloader within sub-component which is a sheet modal. Preloaders initialize themselves off of the pageInit event, so it’s not properly initializing within the sub-component because it doesn’t find the element.

I’m having to do this as a work-around within onUpdated:

if (thisPage && !preloaderInit) {
    thisPage.$el.find('.preloader').each((preloaderEl) => {
        $f7.preloader.init(preloaderEl);
        preloaderInit = true;
    });
 }

I’m not sure if this is an expected limitation or if I’m just misusing the sub-components in some way.

Interesting, but can you give a more complete example so I can check/replicate the issue?

Sorry, was away from work for a bit there.

I think I’ve found a minimum example to reproduce the issue. Try this when you get a chance:

I believe the crux of the issue is a component within a component, that are not actual routable page components. When executing the code in the gist within my application, the Button component mounts after the page init, and the page init would be firing the initialization of the preloader.

image

So you should see a blank filled button with no spinning preloader, and when inspecting the page you should see it’s uninitialized:

image

Thanks, yes, I see there is a currently issue with mount callback order for deeply nested custom components. While I am on it, for now, it is safe to call $f7.preloader.init in component with preloaded, like so according to your gist:

const ComponentButton = (props, { $onMounted, $f7, $el }) => {

  $onMounted(() => {
      $f7.preloader.init($el.value.find('.preloader'))
      console.log("[TEST] CHILD BUTTON MOUNTED");
  });

  return () => (
      <button
          class="button button-fill button-preloader button-loading"
          onclick={() => props.fnClicked()}>
          <span class="preloader"></span>
          <span>{props.label}</span>
      </button>
  )
}

Thanks! That makes more sense than what I was doing.