redoc/lib/components/JsonSchema/json-schema-lazy.ts

105 lines
3.1 KiB
TypeScript
Raw Normal View History

'use strict';
import { Component, ElementRef, ViewContainerRef, OnDestroy, Input,
AfterViewInit, ComponentResolver, Renderer } from '@angular/core';
2016-05-06 12:46:41 +03:00
import { CORE_DIRECTIVES } from '@angular/common';
2016-05-06 12:46:41 +03:00
import { JsonSchema } from './json-schema';
import { OptionsService } from '../../services/options.service';
2016-06-22 21:17:48 +03:00
import { SpecManager } from '../../utils/SpecManager';
2016-02-07 17:11:15 +03:00
var cache = {};
@Component({
selector: 'json-schema-lazy',
template: '',
directives: [CORE_DIRECTIVES]
})
export class JsonSchemaLazy implements OnDestroy, AfterViewInit {
@Input() pointer: string;
@Input() auto: boolean;
@Input() isRequestSchema: boolean;
@Input() final: boolean = false;
@Input() nestOdd: boolean;
@Input() childFor: string;
@Input() isArray: boolean;
loaded: boolean = false;
constructor(private specMgr:SpecManager, private location:ViewContainerRef, private elementRef:ElementRef,
private resolver:ComponentResolver, private optionsService:OptionsService, private _renderer: Renderer) {
}
2016-02-07 17:11:15 +03:00
normalizePointer() {
let schema = this.specMgr.byPointer(this.pointer);
2016-02-07 17:11:15 +03:00
return schema && schema.$ref || this.pointer;
}
2016-05-20 19:28:16 +03:00
_loadAfterSelf() {
2016-06-22 12:45:03 +03:00
// FIXME: get rid of DynamicComponentLoader as it is deprecated
return this.resolver.resolveComponent(JsonSchema).then(componentFactory => {
let contextInjector = this.location.parentInjector;
let compRef = this.location.createComponent(
componentFactory, null, contextInjector, null);
this.initComponent(compRef.instance);
this._renderer.setElementAttribute(compRef.location.nativeElement, 'class', this.location.element.nativeElement.className);
compRef.changeDetectorRef.detectChanges();
2016-05-20 19:28:16 +03:00
return compRef;
}).catch(err => {
console.log(err);
throw err;
2016-05-20 19:28:16 +03:00
});
}
load() {
2016-05-06 12:46:41 +03:00
if (this.optionsService.options.disableLazySchemas) return;
if (this.loaded) return;
if (this.pointer) {
2016-05-20 19:28:16 +03:00
this._loadAfterSelf();
}
this.loaded = true;
}
2016-02-07 17:11:15 +03:00
// cache JsonSchema view
loadCached() {
this.pointer = this.normalizePointer();
2016-02-07 17:11:15 +03:00
if (cache[this.pointer]) {
cache[this.pointer].then((compRef) => {
setTimeout( ()=> {
let $element = compRef.location.nativeElement;
2016-02-07 17:11:15 +03:00
2016-06-22 19:13:57 +03:00
// skip caching view with tabs inside (discriminator)
// as it needs attached controller
if (compRef.instance.hasDescendants || compRef.instance._hasSubSchemas) {
2016-06-22 19:13:57 +03:00
this._loadAfterSelf();
2016-02-07 17:11:15 +03:00
return;
}
insertAfter($element.cloneNode(true), this.elementRef.nativeElement);
2016-02-07 17:11:15 +03:00
} );
});
} else {
2016-05-20 19:28:16 +03:00
cache[this.pointer] = this._loadAfterSelf();
2016-02-07 17:11:15 +03:00
}
}
initComponent(instance:JsonSchema) {
Object.assign(instance, this);
}
2016-02-07 17:11:15 +03:00
ngAfterViewInit() {
if (this.optionsService.options.disableLazySchemas) {
this._loadAfterSelf();
return;
}
2016-02-07 17:11:15 +03:00
if (!this.auto) return;
this.loadCached();
}
ngOnDestroy() {
// clear cache
cache = {};
}
2016-02-07 17:11:15 +03:00
}
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}