今日四个问题 1.创建动态组件的原理 2.@ViewChild的作用 3.module中entryComponents的作用 4.装饰器Component的host属性什么时候没有的

问题4

host属性还有,这个属性是从指令继承的,单位的项目可能是tslint的警告,周一再看下。

问题1,2,3貌似是同一块的知识点。

问题3

entryComponents这个配置项,注释如下

The set of components to compile when this NgModule is defined, so that they can be dynamically loaded into the view.

For each component listed here, Angular creates a ComponentFactory and stores it in the ComponentFactoryResolver.

Angular automatically adds components in the module's bootstrap and route definitions into the entryComponents list. Use this option to add components that are bootstrapped 
compile 编译
dynamically 动态地

可见这个配置就是为了动态加载组件,对于这里列出的每个组件,Angular创建一个ComponentFactory并将其存储在ComponentFactoryResolver中。

问题1
动态组件的创建

第一步,定义一个组件component.ts和模板html搞定。

第二步,创建组件容器(container)。容器可以是任意的 DOM 元素或组件。

这时候引出来问题2@ViewChild了。

通过 ViewChild 装饰器来获取视图中的模板元素(下面是通过模板变量获取)。通过参数可以获取ViewContainerRef 实例。

@ViewChild("alertContainer", { read: ViewContainerRef }) container: ViewContainerRef;

ViewContainerRef 用于表示一个视图容器,可添加一个或多个视图。

通过 ViewContainerRef 实例,我们可以基于 TemplateRef 实例创建内嵌视图,并能指定内嵌视图的插入位置,也可以方便对视图容器中已有的视图进行管理。

简而言之,ViewContainerRef 的主要作用是创建和管理内嵌视图或组件视图。

第三步,动态创建组件。

注入 ComponentFactoryResolver 服务对象。该 ComponentFactoryResolver 服务对象中,提供了一个很重要的方法 - resolveComponentFactory() ,该方法接收一个组件类作为参数,并返回 ComponentFactory

ComponentFactoryResolver 抽象类

/**
 * A simple registry that maps `Components` to generated `ComponentFactory` classes
 * that can be used to create instances of components.
 * Use to obtain the factory for a given component type,
 * then use the factory's `create()` method to create a component of that type.
 *
 * @see [Dynamic Components](guide/dynamic-component-loader)
 * @publicApi
 */
export declare abstract class ComponentFactoryResolver {
    static NULL: ComponentFactoryResolver;
    /**
     * Retrieves the factory object that creates a component of the given type.
     * @param component The component type.
     */
    abstract resolveComponentFactory<T>(component: Type<T>): ComponentFactory<T>;
}

在 AppComponent 组件构造函数中,注入 ComponentFactoryResolver 服务:

constructor(private resolver: ComponentFactoryResolver) {}

ComponentFactory 抽象类:

/**
 * Base class for a factory that can create a component dynamically.
 * Instantiate a factory for a given type of component with `resolveComponentFactory()`.
 * Use the resulting `ComponentFactory.create()` method to create a component of that type.
 *
 * @see [Dynamic Components](guide/dynamic-component-loader)
 *
 * @publicApi
 */
declare abstract class ComponentFactory<C> {
    /**
     * The component's HTML selector.
     */
    abstract get selector(): string;
    /**
     * The type of component the factory will create.
     */
    abstract get componentType(): Type<any>;
    /**
     * Selector for all <ng-content> elements in the component.
     */
    abstract get ngContentSelectors(): string[];
    /**
     * The inputs of the component.
     */
    abstract get inputs(): {
        propName: string;
        templateName: string;
    }[];
    /**
     * The outputs of the component.
     */
    abstract get outputs(): {
        propName: string;
        templateName: string;
    }[];
    /**
     * Creates a new component.
     */
    abstract create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string | any, ngModule?: NgModuleRef<any>): ComponentRef<C>;
}

调用 ComponentFactory 实例的 create() 方法,来创建组件。

createComponent(type) {
   this.container.clear(); 
   const factory: ComponentFactory = 
     this.resolver.resolveComponentFactory(AlertComponent);
   this.componentRef: ComponentRef = this.container.createComponent(factory);
}

另外不能忘记销毁组件:

ngOnDestroy() {
 this.componentRef.destroy(); 
}

问题都解决了,新问题

1.动态创建组件为什么不直接用ngif,有什么区别,什么不同的使用场景。

2.抽象类是什么,与接口的区别。

原文地址:https://www.cnblogs.com/have-a-try/p/12896336.html