UNPKG

adonisjs-livewire

Version:

A front-end framework for AdonisJS

101 lines (100 loc) 4.32 kB
import ComponentHook from '../../component_hook.js'; import { getLivewireContext, store } from '../../store.js'; import Lazy from './lazy.js'; export class SupportLazyLoading extends ComponentHook { async mount(params) { const args = params ?? {}; let hasLazyParam = args.hasOwnProperty('lazy'); let lazyProperty = args.lazy ?? false; let isolate = false; const lazyDecorator = this.component .getDecorators() .find((decorator) => decorator instanceof Lazy); if (hasLazyParam && !lazyProperty) return; if (!hasLazyParam && !lazyDecorator) return; if (lazyDecorator) { isolate = lazyDecorator.isolate; } this.component.skipMount(); store(this.component).set('isLazyLoadMounting', true); store(this.component).set('isLazyIsolated', isolate); this.component.skipRender(await this.generatePlaceholderHtml(params)); } async hydrate(memo) { if (memo['lazyLoaded']) return; if (memo['lazyLoaded'] === true) return; this.component.skipHydrate(); store(this.component).set('isLazyLoadHydrating', true); } async dehydrate(context) { if (store(this.component).get('isLazyLoadMounting') === true) { context.addMemo('lazyLoaded', false); context.addMemo('lazyIsolated', store(this.component).get('isLazyIsolated')); } else if (store(this.component).get('isLazyLoadHydrating') === true) { context.addMemo('lazyLoaded', true); } } async generatePlaceholderHtml(params) { const Livewire = await this.app.container.make('livewire'); let { context } = getLivewireContext(); let placeholder = await this.getPlaceholderHtml(params); context.addMemo('__for_mount', params); let encoded = JSON.stringify(await Livewire.snapshot(this.component, context)); return Livewire.insertAttributesIntoHtmlRoot(placeholder, { 'x-intersect': `$wire.__lazyLoad('${encoded}')`, }); } async getPlaceholderHtml(params) { if (!this.component['placeholder']) { return '<div></div>'; } return await this.component.view.renderRaw(await this.component['placeholder'](params)); } async call(method, params, _returnEarly) { if (method !== '__lazyLoad') return; // const { Livewire } = await this.app.container.resolveBinding('Adonis/Addons/Livewire') let data = JSON.parse(params[0]); if (data.memo.__for_mount) { // TODO: move this to a separate hook let component = this.component; if (typeof component['mount'] === 'function') { const resolvedParams = [data.memo.__for_mount]; const isResourceModel = (value) => { if (!value) { return false; } return (typeof value['findForRequest'] === 'function' || typeof value['findOrFail'] === 'function' || typeof value['findRelatedForRequest'] === 'function'); }; if (component['bindings'] && component['bindings']['mount']) { for (let index = 1; index < component['bindings']['mount'].length; index++) { const binding = component['bindings']['mount'][index]; if (isResourceModel(binding.type)) { resolvedParams.push(await binding.type.findOrFail(data.memo.__for_mount[binding.name])); } else { resolvedParams.push(data.memo.__for_mount[binding.name]); } } } //@ts-ignore await component.mount(...resolvedParams); } else { for (let paramKey in data.memo.__for_mount) { if (paramKey in component) { component[paramKey] = data.memo.__for_mount[paramKey]; } } } delete data.memo.for_mount; } } }