zl程序教程

您现在的位置是:首页 >  其它

当前栏目

ng-template和ngTemplateOutlet

Template NG
2023-09-14 09:04:01 时间

我们可以使用ng-container, ng-template和ngTemplateOutlet 三者的配合,实现动态渲染某个模板视图的目的。

ng build之后,在Chrome开发者工具里看到ng文件夹下对应的html文件:

<ng-template #inputTemplate>
    <input>
    <h1>ngTemplateOutlet的用法</h1>
</ng-template>

<ng-container *ngTemplateOutlet="inputTemplate"></ng-container>

tNode指向源代码里的ng-container节点:

ngTemplateOutlet的实现:

/**
 * @ngModule CommonModule
 *
 * @description
 *
 * Inserts an embedded view from a prepared `TemplateRef`.
 *
 * You can attach a context object to the `EmbeddedViewRef` by setting `[ngTemplateOutletContext]`.
 * `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
 * by the local template `let` declarations.
 *
 * @usageNotes
 * ```
 * <ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
 * ```
 *
 * Using the key `$implicit` in the context object will set its value as default.
 *
 * ### Example
 *
 * {@example common/ngTemplateOutlet/ts/module.ts region='NgTemplateOutlet'}
 *
 * @publicApi
 */
@Directive({selector: '[ngTemplateOutlet]'})
export class NgTemplateOutlet implements OnChanges {
  private _viewRef: EmbeddedViewRef<any>|null = null;

  /**
   * A context object to attach to the {@link EmbeddedViewRef}. This should be an
   * object, the object's keys will be available for binding by the local template `let`
   * declarations.
   * Using the key `$implicit` in the context object will set its value as default.
   */
  @Input() public ngTemplateOutletContext: Object|null = null;

  /**
   * A string defining the template reference and optionally the context object for the template.
   */
  @Input() public ngTemplateOutlet: TemplateRef<any>|null = null;

  constructor(private _viewContainerRef: ViewContainerRef) {}

  ngOnChanges(changes: SimpleChanges) {
    const recreateView = this._shouldRecreateView(changes);

    if (recreateView) {
      const viewContainerRef = this._viewContainerRef;

      if (this._viewRef) {
        viewContainerRef.remove(viewContainerRef.indexOf(this._viewRef));
      }

      this._viewRef = this.ngTemplateOutlet ?
          viewContainerRef.createEmbeddedView(this.ngTemplateOutlet, this.ngTemplateOutletContext) :
          null;
    } else if (this._viewRef && this.ngTemplateOutletContext) {
      this._updateExistingContext(this.ngTemplateOutletContext);
    }
  }

还是老套路,在ngOnChanges里调用ViewContainerRef.createEmbeddedView: