feat(aio): add component for lazy-loading custom element (#23944)
PR Close #23944
This commit is contained in:
parent
434eb971e4
commit
c30fc52d99
@ -6,8 +6,11 @@ import {
|
|||||||
ELEMENT_MODULE_PATHS_AS_ROUTES,
|
ELEMENT_MODULE_PATHS_AS_ROUTES,
|
||||||
ELEMENT_MODULE_PATHS_TOKEN
|
ELEMENT_MODULE_PATHS_TOKEN
|
||||||
} from './element-registry';
|
} from './element-registry';
|
||||||
|
import { LazyCustomElementComponent } from './lazy-custom-element.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
declarations: [ LazyCustomElementComponent ],
|
||||||
|
exports: [ LazyCustomElementComponent ],
|
||||||
providers: [
|
providers: [
|
||||||
ElementsLoader,
|
ElementsLoader,
|
||||||
{ provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader },
|
{ provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader },
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { Logger } from 'app/shared/logger.service';
|
||||||
|
import { MockLogger } from 'testing/logger.service';
|
||||||
|
import { LazyCustomElementComponent } from './lazy-custom-element.component';
|
||||||
|
import { ElementsLoader } from './elements-loader';
|
||||||
|
|
||||||
|
describe('LazyCustomElementComponent', () => {
|
||||||
|
let mockElementsLoader: jasmine.SpyObj<ElementsLoader>;
|
||||||
|
let mockLogger: MockLogger;
|
||||||
|
let fixture: ComponentFixture<LazyCustomElementComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockElementsLoader = jasmine.createSpyObj<ElementsLoader>('ElementsLoader', [
|
||||||
|
'loadContainingCustomElements',
|
||||||
|
'loadCustomElement',
|
||||||
|
]);
|
||||||
|
|
||||||
|
const injector = TestBed.configureTestingModule({
|
||||||
|
declarations: [ LazyCustomElementComponent ],
|
||||||
|
providers: [
|
||||||
|
{ provide: ElementsLoader, useValue: mockElementsLoader },
|
||||||
|
{ provide: Logger, useClass: MockLogger },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
mockLogger = injector.get(Logger);
|
||||||
|
fixture = TestBed.createComponent(LazyCustomElementComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the HTML content based on the selector', () => {
|
||||||
|
const elem = fixture.nativeElement;
|
||||||
|
|
||||||
|
expect(elem.innerHTML).toBe('');
|
||||||
|
|
||||||
|
fixture.componentInstance.selector = 'foo-bar';
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(elem.innerHTML).toBe('<foo-bar></foo-bar>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should load the specified custom element', () => {
|
||||||
|
expect(mockElementsLoader.loadCustomElement).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
fixture.componentInstance.selector = 'foo-bar';
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(mockElementsLoader.loadCustomElement).toHaveBeenCalledWith('foo-bar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log an error (and abort) if the selector is empty', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(mockElementsLoader.loadCustomElement).not.toHaveBeenCalled();
|
||||||
|
expect(mockLogger.output.error).toEqual([[jasmine.any(Error)]]);
|
||||||
|
expect(mockLogger.output.error[0][0].message).toBe('Invalid selector for \'aio-lazy-ce\': ');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log an error (and abort) if the selector is invalid', () => {
|
||||||
|
fixture.componentInstance.selector = 'foo-bar><script></script><foo-bar';
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(mockElementsLoader.loadCustomElement).not.toHaveBeenCalled();
|
||||||
|
expect(mockLogger.output.error).toEqual([[jasmine.any(Error)]]);
|
||||||
|
expect(mockLogger.output.error[0][0].message).toBe(
|
||||||
|
'Invalid selector for \'aio-lazy-ce\': foo-bar><script></script><foo-bar');
|
||||||
|
});
|
||||||
|
});
|
27
aio/src/app/custom-elements/lazy-custom-element.component.ts
Normal file
27
aio/src/app/custom-elements/lazy-custom-element.component.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Component, ElementRef, Input, OnInit } from '@angular/core';
|
||||||
|
import { Logger } from 'app/shared/logger.service';
|
||||||
|
import { ElementsLoader } from './elements-loader';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'aio-lazy-ce',
|
||||||
|
template: '',
|
||||||
|
})
|
||||||
|
export class LazyCustomElementComponent implements OnInit {
|
||||||
|
@Input() selector = '';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private elementRef: ElementRef,
|
||||||
|
private elementsLoader: ElementsLoader,
|
||||||
|
private logger: Logger,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (!this.selector || /[^\w-]/.test(this.selector)) {
|
||||||
|
this.logger.error(new Error(`Invalid selector for 'aio-lazy-ce': ${this.selector}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.elementRef.nativeElement.innerHTML = `<${this.selector}></${this.selector}>`;
|
||||||
|
this.elementsLoader.loadCustomElement(this.selector);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user