Angular ivy 中的 renderComponent 带有额外的 component/directive 声明
renderComponent in Angular ivy with extra component/directive declarations
这里是在ivy中渲染动态惰性组件的例子:
import { ɵrenderComponent as renderComponent, Injector } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-lazy></app-lazy>
`
})
export class AppComponent {
constructor(injector: Injector) {
import('./lazy.component').then(({ LazyComponent }) => {
renderComponent(LazyComponent, {
injector,
host: 'app-lazy'
});
});
}
}
如果我们需要在lazy.component
中使用额外的component/directive怎么办?
您需要一个自定义装饰器
import {
Component,
Type,
ɵComponentDef as ComponentDef,
ɵDirectiveDef as DirectiveDef,
ɵPipeDef as PipeDef
} from '@angular/core';
@Component(...)
@ComponentDeps({
directives: [...], //***extra component/directive you want***
pipes: [...] //***extra pipe, like: JsonPipe...***
})
export class LazyComponent{
...
}
export interface ComponentDepsConfig {
directives?: Type<any>[];
pipes?: Type<any>[];
}
function getDirectiveDef<T>(t: Type<T>): DirectiveDef<T> {
if (t['ɵdir']) {
return t['ɵdir'] as DirectiveDef<T>;
}
if (t['ɵcmp']) {
return t['ɵcmp'] as ComponentDef<T>;
}
throw new Error('No Angular definition found for ' + t.name);
}
function getDirectiveDefs(types: Type<any>[]): DirectiveDef<any>[] {
return types.map(t => getDirectiveDef(t));
}
function getPipeDef<T>(t: Type<T>): PipeDef<T> {
if (t['ɵpipe']) {
return t['ɵpipe'] as PipeDef<T>;
}
throw new Error('No Angular definition found for ' + t.name);
}
export function getPipeDefs(types: Type<any>[]): PipeDef<any>[] {
return types.map(t => getPipeDef(t));
}
export function ComponentDeps(config: ComponentDepsConfig) {
return (componentType: Type<any>) => {
const def = componentType['ɵcmp'] || componentType['ngComponentDef'];
// directives or components
def.directiveDefs = [
...getDirectiveDefs(config.directives || [])
];
// pipes
def.pipeDefs = [
...getPipeDefs(config.pipes || [])
];
};
}
function setScopeOnDeclaredComponents(moduleType: Type<any>, component: any) {
const transitiveScopes = ɵtransitiveScopesFor(moduleType);
const componentDef = component[ɵNG_COMP_DEF];
if (!componentDef) {
console.error('not define comp')
}
ɵpatchComponentDefWithScope(componentDef, transitiveScopes);
}
这里是在ivy中渲染动态惰性组件的例子:
import { ɵrenderComponent as renderComponent, Injector } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-lazy></app-lazy>
`
})
export class AppComponent {
constructor(injector: Injector) {
import('./lazy.component').then(({ LazyComponent }) => {
renderComponent(LazyComponent, {
injector,
host: 'app-lazy'
});
});
}
}
如果我们需要在lazy.component
中使用额外的component/directive怎么办?
您需要一个自定义装饰器
import {
Component,
Type,
ɵComponentDef as ComponentDef,
ɵDirectiveDef as DirectiveDef,
ɵPipeDef as PipeDef
} from '@angular/core';
@Component(...)
@ComponentDeps({
directives: [...], //***extra component/directive you want***
pipes: [...] //***extra pipe, like: JsonPipe...***
})
export class LazyComponent{
...
}
export interface ComponentDepsConfig {
directives?: Type<any>[];
pipes?: Type<any>[];
}
function getDirectiveDef<T>(t: Type<T>): DirectiveDef<T> {
if (t['ɵdir']) {
return t['ɵdir'] as DirectiveDef<T>;
}
if (t['ɵcmp']) {
return t['ɵcmp'] as ComponentDef<T>;
}
throw new Error('No Angular definition found for ' + t.name);
}
function getDirectiveDefs(types: Type<any>[]): DirectiveDef<any>[] {
return types.map(t => getDirectiveDef(t));
}
function getPipeDef<T>(t: Type<T>): PipeDef<T> {
if (t['ɵpipe']) {
return t['ɵpipe'] as PipeDef<T>;
}
throw new Error('No Angular definition found for ' + t.name);
}
export function getPipeDefs(types: Type<any>[]): PipeDef<any>[] {
return types.map(t => getPipeDef(t));
}
export function ComponentDeps(config: ComponentDepsConfig) {
return (componentType: Type<any>) => {
const def = componentType['ɵcmp'] || componentType['ngComponentDef'];
// directives or components
def.directiveDefs = [
...getDirectiveDefs(config.directives || [])
];
// pipes
def.pipeDefs = [
...getPipeDefs(config.pipes || [])
];
};
}
function setScopeOnDeclaredComponents(moduleType: Type<any>, component: any) {
const transitiveScopes = ɵtransitiveScopesFor(moduleType);
const componentDef = component[ɵNG_COMP_DEF];
if (!componentDef) {
console.error('not define comp')
}
ɵpatchComponentDefWithScope(componentDef, transitiveScopes);
}